mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-12-12 14:17:46 +00:00
Easily launch multiple platforms on a single server
By using a web proxy on the host, it's now extremely easy to launch multiple platforms on a single server.
This commit is contained in:
parent
f45a24caea
commit
a70d48c6bb
@ -2,6 +2,7 @@
|
||||
|
||||
## Latest
|
||||
|
||||
- [Feature] Multiple platforms on a single server \o/
|
||||
- [Feature] Easily configure web proxy on the host
|
||||
- [Bugfix] Fix `images pull all` command which failed on "all" image
|
||||
- [Improvement] Add configurable mongodb, SMTP and rabbitmq authentication
|
||||
|
@ -148,6 +148,36 @@ If you have configured your platform to use SSL/TLS certificates for HTTPS acces
|
||||
tutor local https create
|
||||
tutor local https renew
|
||||
|
||||
Running multiple Open edX platforms on a single server
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With Tutor, it is easy to run multiple Open edX instances on a single server. To do so, the following configuration parameters must be different for all platforms:
|
||||
|
||||
- ``TUTOR_ROOT``: so that configuration, environment and data are not mixed up between platforms.
|
||||
- ``LOCAL_PROJECT_NAME``: the various docker-compose projects cannot share the same name.
|
||||
- ``NGINX_HTTP_PORT``, ``NGINX_HTTPS_PORT``: ports cannot be shared by two different containers.
|
||||
- ``LMS_HOST``, ``CMS_HOST``: the different platforms must be accessible from different domain (or subdomain) names.
|
||||
|
||||
In addition, a web proxy must be setup on the host, as described :ref:`above <web_proxy>`.
|
||||
|
||||
As an example, here is how to launch two different platforms, with nginx running as a web proxy:
|
||||
|
||||
# platform 1
|
||||
export TUTOR_ROOT=~/openedx/site1
|
||||
tutor config save --set WEB_PROXY=true --set LOCAL_PROJECT_NAME=tutor_site1 --set NGINX_HTTP_PORT=81 --set NGINX_HTTPS_PORT=481
|
||||
tutor local quickstart
|
||||
sudo ln -s $(tutor config printroot)/env/local/proxy/nginx/openedx.conf /etc/nginx/sites-enabled/site1.conf
|
||||
|
||||
|
||||
# platform 2
|
||||
export TUTOR_ROOT=~/openedx/site2
|
||||
tutor config save --set WEB_PROXY=true --set LOCAL_PROJECT_NAME=tutor_site2 --set NGINX_HTTP_PORT=82 --set NGINX_HTTPS_PORT=482
|
||||
tutor local quickstart
|
||||
sudo ln -s $(tutor config printroot)/env/local/proxy/nginx/openedx.conf /etc/nginx/sites-enabled/site2.conf
|
||||
|
||||
You should then have two different platforms, completely isolated from one another, running on the same server.
|
||||
|
||||
|
||||
Loading different production settings for ``edx-platform``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -34,7 +34,7 @@ If you'd rather use a graphical user interface for viewing logs, you are encoura
|
||||
"Cannot start service nginx: driver failed programming external connectivity"
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
The containerized Nginx needs to listen to ports 80 and 443 on the host. If there is already a webserver, such as Apache or Nginx, running on the host, the nginx container will not be able to start. To solve this issue, check :ref:`web_proxy`.
|
||||
The containerized Nginx needs to listen to ports 80 and 443 on the host. If there is already a webserver, such as Apache or Nginx, running on the host, the nginx container will not be able to start. To solve this issue, check :ref:`out to setup a web proxy <web_proxy>`.
|
||||
|
||||
Help! The Docker containers are eating all my RAM/CPU/CHEESE
|
||||
------------------------------------------------------------
|
||||
|
@ -22,9 +22,7 @@ from . import ops
|
||||
def local():
|
||||
pass
|
||||
|
||||
@click.command(
|
||||
help="Configure and run Open edX from scratch"
|
||||
)
|
||||
@click.command(help="Configure and run Open edX from scratch")
|
||||
@click.option("-p", "--pullimages", "pullimages_", is_flag=True, help="Update docker images")
|
||||
@opts.root
|
||||
def quickstart(pullimages_, root):
|
||||
@ -42,16 +40,13 @@ def quickstart(pullimages_, root):
|
||||
click.echo(fmt.title("Starting the platform in detached mode"))
|
||||
start.callback(root, True)
|
||||
|
||||
@click.command(
|
||||
help="Update docker images",
|
||||
)
|
||||
@click.command(help="Update docker images")
|
||||
@opts.root
|
||||
def pullimages(root):
|
||||
docker_compose(root, "pull")
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, "pull")
|
||||
|
||||
@click.command(
|
||||
help="Run all configured Open edX services",
|
||||
)
|
||||
@click.command(help="Run all configured Open edX services")
|
||||
@opts.root
|
||||
@click.option("-d", "--detach", is_flag=True, help="Start in daemon mode")
|
||||
def start(root, detach):
|
||||
@ -59,11 +54,11 @@ def start(root, detach):
|
||||
if detach:
|
||||
command.append("-d")
|
||||
|
||||
docker_compose(root, *command)
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, *command)
|
||||
|
||||
if detach:
|
||||
click.echo(fmt.info("The Open edX platform is now running in detached mode"))
|
||||
config = tutor_config.load(root)
|
||||
http = "https" if config["ACTIVATE_HTTPS"] else "http"
|
||||
urls = []
|
||||
if not config["ACTIVATE_HTTPS"] and not config["WEB_PROXY"]:
|
||||
@ -81,7 +76,8 @@ def start(root, detach):
|
||||
@click.command(help="Stop a running platform",)
|
||||
@opts.root
|
||||
def stop(root):
|
||||
docker_compose(root, "rm", "--stop", "--force")
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, "rm", "--stop", "--force")
|
||||
|
||||
@click.command(
|
||||
help="""Restart some components from a running platform.
|
||||
@ -96,7 +92,8 @@ def restart(root, service):
|
||||
command += ["lms", "cms", "lms_worker", "cms_worker"]
|
||||
elif service != "all":
|
||||
command += [service]
|
||||
docker_compose(root, *command)
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, *command)
|
||||
|
||||
@click.command(
|
||||
help="Run a command in one of the containers",
|
||||
@ -116,7 +113,8 @@ def run(root, service, command, args):
|
||||
run_command.append(command)
|
||||
if args:
|
||||
run_command += args
|
||||
docker_compose(root, *run_command)
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, *run_command)
|
||||
|
||||
@click.command(
|
||||
help="Create databases and run database migrations",
|
||||
@ -134,16 +132,18 @@ def init_mysql(root):
|
||||
if os.path.exists(mysql_data_path):
|
||||
return
|
||||
click.echo(fmt.info("Initializing MySQL database..."))
|
||||
docker_compose(root, "up", "-d", "mysql")
|
||||
docker_compose(root, config, "up", "-d", "mysql")
|
||||
while True:
|
||||
click.echo(fmt.info(" waiting for mysql initialization"))
|
||||
# TODO this is duplicate code with the docker_compose function. We
|
||||
# should rely on a dedicated function in utils module.
|
||||
logs = subprocess.check_output([
|
||||
"docker-compose", "-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
||||
"--project-name", "tutor_local", "logs", "mysql",
|
||||
"--project-name", config["LOCAL_PROJECT_NAME"], "logs", "mysql",
|
||||
])
|
||||
if b"MySQL init process done. Ready for start up." in logs:
|
||||
click.echo(fmt.info("MySQL database initialized"))
|
||||
docker_compose(root, "stop", "mysql")
|
||||
docker_compose(root, config, "stop", "mysql")
|
||||
return
|
||||
sleep(4)
|
||||
|
||||
@ -219,7 +219,8 @@ def logs(root, follow, tail, service):
|
||||
if tail is not None:
|
||||
command += ["--tail", str(tail)]
|
||||
command += service
|
||||
docker_compose(root, *command)
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, *command)
|
||||
|
||||
@click.command(help="Create an Open edX user and interactively set their password")
|
||||
@opts.root
|
||||
@ -261,12 +262,13 @@ def portainer(root, port):
|
||||
utils.docker_run(*docker_run)
|
||||
|
||||
def run_bash(root, service, command):
|
||||
docker_compose(root, "run", "--rm", service, "bash", "-e", "-c", command)
|
||||
config = tutor_config.load(root)
|
||||
docker_compose(root, config, "run", "--rm", service, "bash", "-e", "-c", command)
|
||||
|
||||
def docker_compose(root, *command):
|
||||
def docker_compose(root, config, *command):
|
||||
return utils.docker_compose(
|
||||
"-f", tutor_env.pathjoin(root, "local", "docker-compose.yml"),
|
||||
"--project-name", "tutor_local",
|
||||
"--project-name", config["LOCAL_PROJECT_NAME"],
|
||||
*command
|
||||
)
|
||||
|
||||
|
@ -21,6 +21,7 @@ DOCKER_IMAGE_NGINX: "nginx:1.13"
|
||||
DOCKER_IMAGE_RABBITMQ: "rabbitmq:3.6.10"
|
||||
DOCKER_IMAGE_SMTP: "namshi/smtp:latest"
|
||||
DOCKER_REGISTRY: ""
|
||||
LOCAL_PROJECT_NAME: "tutor_local"
|
||||
ELASTICSEARCH_HOST: "elasticsearch"
|
||||
ELASTICSEARCH_PORT: 9200
|
||||
MEMCACHED_HOST: "memcached"
|
||||
|
Loading…
Reference in New Issue
Block a user