-
Notifications
You must be signed in to change notification settings - Fork 3
Systemd, ENV, latest stable Moodle #6
Changes from all commits
0741191
68bf95b
3d6967b
87f7697
a4f47d2
b689c3a
65223a2
f4818a4
494e88e
c5fe0b0
961eb85
827fccf
2c867b2
ecea819
5fe03d2
aa36212
21390f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
|
||
# Moodle version | ||
MOODLE_DOWNLOAD_FILE=moodle-latest-35.tgz | ||
MOODLE_TRACK=stable35 | ||
MOODLE_VERSION=3.5 | ||
ONELOGIN_PLUGIN_VER=v2.5.1 | ||
|
@@ -10,7 +11,11 @@ PHP_VERSION=7.2 | |
# Nginx version | ||
NGINX_VERSION=1.14.0-0+xenial1 | ||
|
||
# Docker | ||
DOCKER_REGISTRY_URL=docker.sdelements.com:443/moodle | ||
|
||
# Moodle variables | ||
# WWWROOT MUST be IP or FQDN | ||
MOODLE_WWWROOT=https://localhost | ||
MOODLE_DATAROOT=/opt/moodle/moodledata | ||
[email protected] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,80 +3,30 @@ | |
## Summary | ||
This project deploys the Moodle (Modular Object-Oriented Dynamic Learning Environment) course management system using one Docker container that runs both Nginx and PHP/PHP-FPM services | ||
|
||
## Setup | ||
## Local Environment Setup | ||
|
||
1. Install Docker on your system. | ||
##### CentOS 7 | ||
```bash | ||
# Optional | ||
yum install -y yum-utils device-mapper-persistent-data lvm2 | ||
|
||
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | ||
yum install -y docker-ce | ||
systemctl enable docker.service | ||
systemctl start docker.service | ||
systemctl status docker.service | ||
|
||
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm | ||
yum install -y python2-pip | ||
pip install docker-compose | ||
``` | ||
|
||
##### Ubuntu 16.04 | ||
```bash | ||
# Remove the Kubernetes Apt source file in `/etc/apt/sources.list.d` or add the Apt key if you require it | ||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6A030B21BA07F4FB | ||
|
||
# Dependencies | ||
apt-get update | ||
apt-get install -y apt-transport-https ca-certificates curl software-properties-common | ||
|
||
# Apt key | ||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - | ||
apt-key fingerprint 0EBFCD88 | ||
|
||
# Remove legacy docker, add repo, install latest docker | ||
apt-get remove -y docker docker-engine docker.io | ||
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | ||
apt-get update | ||
apt-get install -y docker-ce | ||
systemctl enable docker.service | ||
systemctl start docker.service | ||
systemctl status docker.service | ||
|
||
# Docker compose | ||
curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose | ||
chmod +x /usr/local/bin/docker-compose | ||
docker-compose --version | ||
./setup.sh | ||
``` | ||
|
||
2. Copy/clone dockerfiles from the `moodle-docker` repository and build the containers. Note: `docker-postgres` is a Git submodule in `moodle-docker`. | ||
```bash | ||
# Moodle repo | ||
git clone [email protected].com:deployment/moodle-docker.git | ||
git clone https://github.com/SecurityCompass/moodle-docker.git | ||
|
||
# Pull submodules into local repo | ||
git submodule update --init | ||
|
||
# Postgres entrypoint has to be executable. Git holds the executable bit but sometimes the file is created with incorrect permissions. | ||
chmod +x moodle-docker/docker-postgres/9.6/alpine/docker-entrypoint.sh | ||
``` | ||
|
||
3. Copy your SSL certificate and key into the `conf/etc/nginx/ssl/` dir as `moodle.crt` and `moodle.key`. The included pair are self-signed and can be used (TESTING ONLY). | ||
|
||
Instructions below to generate your own self-signed certificate pair. | ||
|
||
4. Create data directory for Moodle (on the host VM) | ||
```bash | ||
mkdir -p /opt/moodle/moodledata | ||
chmod 777 /opt/moodle/moodledata | ||
``` | ||
4. Customize `.env` according to your environment. Most notably `MOODLE_WWWROOT` (based on your instance IP/FQDN) | ||
|
||
5. Customize `.env` according to your environment. Most notably `MOODLE_VERSION` and `MOODLE_WWWROOT` (based on your instance IP/FQDN) | ||
|
||
6. Build, configure and start the docker containers with docker-compose. | ||
5. Build, configure and start the docker containers with docker-compose. | ||
* `-d` toggles foreground/background | ||
* `-V` recreates anonymous docker volumes (DATA LOSS!) | ||
|
||
Here are some ways to run these containers: | ||
|
||
|
@@ -89,31 +39,28 @@ This project deploys the Moodle (Modular Object-Oriented Dynamic Learning Enviro | |
##### Deploy locally (Full stack) | ||
```bash | ||
cd moodle-docker | ||
docker-compose -f docker-compose.yml -f dc.local.yml up --force-recreate --always-recreate-deps -d -V | ||
docker-compose -f docker-compose.yml -f dc.local.yml up --force-recreate --always-recreate-deps -d | ||
``` | ||
* Nginx ports: `8443/8080` | ||
* Postgres port: `N/A` | ||
|
||
##### Deploy in production (Full stack) | ||
```bash | ||
cd moodle-docker | ||
docker-compose -f docker-compose.yml -f dc.prod.yml up --force-recreate --always-recreate-deps -d -V | ||
docker-compose -f docker-compose.yml -f dc.prod.yml up --force-recreate --always-recreate-deps -d | ||
``` | ||
* Nginx ports: `443/80` | ||
* Postgres port: `N/A` | ||
|
||
##### Deploy Web server and DB separately (separate servers) | ||
```bash | ||
cd moodle-docker | ||
docker-compose -f docker-compose.yml -f dc.prod-dbonly.yml up --force-recreate -d -V postgres | ||
docker-compose -f docker-compose.yml -f dc.prod.yml up --force-recreate --no-deps -d -V nginx-php-moodle | ||
docker-compose -f docker-compose.yml -f dc.prod-dbonly.yml up --force-recreate -d postgres | ||
docker-compose -f docker-compose.yml -f dc.prod.yml up --force-recreate --no-deps -d nginx-php-moodle | ||
``` | ||
* Nginx ports: `8443/8080` | ||
* Postgres port: `5432` | ||
|
||
7. Follow these instructions to setup the Moodle app: | ||
https://securitycompass.atlassian.net/wiki/spaces/DEP/pages/204046339/Moodle+Docker+Deployment | ||
|
||
## Misc. | ||
|
||
* Generate self-signed certificate (TESTING ONLY) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[Unit] | ||
Description=Docker based Moodle Deployment | ||
Documentation=https://github.com/SecurityCompass/moodle-docker | ||
After=docker.service | ||
Requires=docker.service | ||
|
||
[Service] | ||
WorkingDirectory=/etc/moodle-docker | ||
Type=oneshot | ||
RemainAfterExit=yes | ||
|
||
ExecStartPre=-/usr/local/bin/docker-compose --file /etc/moodle-docker/docker-compose.yml pull --quiet | ||
ExecStart=/usr/local/bin/docker-compose --file /etc/moodle-docker/docker-compose.yml --file /etc/moodle-docker/dc.prod.yml up --detach | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the container is managed with systemd we don't want to detach from the container here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its cleaner to detach and let There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not keep it attached and let systemd handling the logging also? Then systemd can detect if the container crashes or stops for some reason. You will also be able to access the logs through docker but it's easier to use journalctl and get all logs at once. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The syslog logging driver should dump everything to a log file, but we could also try the journald logging driver instead: https://docs.docker.com/config/containers/logging/journald/#options |
||
|
||
ExecReload=-/usr/local/bin/docker-compose --file /etc/moodle-docker/docker-compose.yml pull --quiet | ||
ExecReload=/usr/local/bin/docker-compose --file /etc/moodle-docker/docker-compose.yml --file /etc/moodle-docker/dc.prod.yml up --detach | ||
|
||
ExecStop=/usr/local/bin/docker-compose --file /etc/moodle-docker/docker-compose.yml stop | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/bin/sh | ||
after_upgrade() { | ||
: | ||
|
||
systemctl --system daemon-reload >/dev/null || true | ||
if ! systemctl is-enabled moodle-docker >/dev/null | ||
then | ||
systemctl enable moodle-docker >/dev/null || true | ||
systemctl start moodle-docker >/dev/null || true | ||
else | ||
systemctl restart moodle-docker >/dev/null || true | ||
fi | ||
} | ||
|
||
after_install() { | ||
: | ||
#!/usr/bin/env bash | ||
|
||
systemctl --system daemon-reload >/dev/null || true | ||
systemctl enable moodle-docker >/dev/null || true | ||
# Skip starting since we need to configure `.env` | ||
#systemctl start moodle-docker >/dev/null || true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should remove this line if it's not needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm going to uncomment once I automate a couple more things:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah alright let's leave this part in for now then. |
||
} | ||
|
||
if [ "${1}" = "configure" ] && [ -z "${2}" ] || \ | ||
[ "${1}" = "abort-remove" ] | ||
then | ||
# "after install" here | ||
# "abort-remove" happens when the pre-removal script failed. | ||
# In that case, this script, which should be idemptoent, is run | ||
# to ensure a clean roll-back of the removal. | ||
after_install | ||
elif [ "${1}" = "configure" ] && [ -n "${2}" ] | ||
then | ||
upgradeFromVersion="${2}" | ||
# "after upgrade" here | ||
# NOTE: This slot is also used when deb packages are removed, | ||
# but their config files aren't, but a newer version of the | ||
# package is installed later, called "Config-Files" state. | ||
# basically, that still looks a _lot_ like an upgrade to me. | ||
after_upgrade "${upgradeFromVersion}" | ||
elif echo "${1}" | grep -E -q "(abort|fail)" | ||
then | ||
echo "Failed to install before the post-installation script was run." >&2 | ||
exit 1 | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/bin/sh | ||
before_remove() { | ||
: | ||
|
||
systemctl stop moodle-docker >/dev/null || true | ||
systemctl disable moodle-docker >/dev/null || true | ||
systemctl --system daemon-reload >/dev/null || true | ||
} | ||
|
||
dummy() { | ||
: | ||
} | ||
|
||
if [ "${1}" = "remove" ] && [ -z "${2}" ] | ||
then | ||
# "before remove" goes here | ||
before_remove | ||
elif [ "${1}" = "upgrade" ] | ||
then | ||
# Executed before the old version is removed | ||
# upon upgrade. | ||
# We should generally not do anything here. The newly installed package | ||
# should do the upgrade, not the uninstalled one, since it can't anticipate | ||
# what new things it will have to do to upgrade for the new version. | ||
dummy | ||
elif echo "${1}" | grep -E -q "(fail|abort)" | ||
then | ||
echo "Failed to install before the pre-removal script was run." >&2 | ||
exit 1 | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a oneshot service? generally that's used for scripts that exit, but this will remain running as a service.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docker-compose
doesn't stay running, the actual containers are managed bydocker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you remove the --detach it will stay running, that way the logs show up properly with journalctl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--detach
is safer in prod because it saves on resources.. plus we should have a proper logging solution vsdocker
->docker-compose
->journalctl
Some more notes here:
docker/compose#4266 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I would much rather we use the 'syslog' docker logging driver and leave compose detached. This is what I'm doing for SDE, and instead of dumping logs into the compose stdout, it will send them to syslog with an appropriate container tag. Let me know if you have questions about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What resources would it be using exactly? The example posted before that comment is the correct way to do this IMO. The proper logging solution is to use this as a simple service and not oneshot. If we send the logs to journald it's easy to then move them elsewhere to a centralized location.
What's the behaviour with stopping a container in a oneshot service? once docker-compose exits the oneshot service will report it's exited successfully. This could leave you in a weird state where the container is running/crashed but systemd is not aware of this.
Also what happens when docker-compose exits but the container stops right after due to an error or some other reason? In this case systemd wont print any errors and the oneshot service will report success even though the container is not running.
Another reason to make this a simple service would be then we can use the Restart and related config fields to ensure the container is brought back up if it exits for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamgilbert just pointed me to this:
https://docs.docker.com/config/containers/logging/journald/#usage
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed further with @hrpatel, I think we are good to go with the oneshot approach.