diff --git a/README.md b/README.md index 1cf0e1becca6e6bd7072a7230555dbbee50449c2..1888bb07d0a7a8923a91940e678930bec25f2938 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,6 @@ Ce dépôt centralise les Dockerfiles et autre ressources utilisées pour constr La documentation pour comprendre et utiliser ce dépôt se trouve sur le Wiki : https://wiki.picasoft.net/doku.php?id=technique:docker:start +Chaque sous-dossier contient les instructions spécifiques à chaque service, mais ne rappelle pas toutes les étapes (construction, test, etc...). Voir le wiki. + Il est important de la mettre à jour en cas de modification majeure sur ce dépôt ou sur la façon de gérer les services. :D diff --git a/docker_test.sh b/docker_test.sh index c4b72d6aa61c94e2b5a22e27b3cdaa5ff5812af6..bcb97376be6aaad272544692d32d571c915c9029 100755 --- a/docker_test.sh +++ b/docker_test.sh @@ -53,13 +53,13 @@ else echo "WARNING : directory does not exist ($1) ; will try to pull" fi -echo -e "\n==== RESET HARD and pull Dockerfiles repository ====" +echo -e "\n==== Pull Dockerfiles repository ====" echo -e "Using branch \033[31m $(git rev-parse --abbrev-ref HEAD)\e[0m, is this correct ? [y/N]" read ans if [ $ans == "y" ]; then - git reset --hard git pull + git checkout -- $1 else echo "Aborting." exit 0 diff --git a/pica-codimd/Dockerfile b/pica-codimd/Dockerfile index c7d9fdccce767d6c04fb58c211595e830e8664c1..38a1892dd11c73759142b7babb1302f30aeffadc 100644 --- a/pica-codimd/Dockerfile +++ b/pica-codimd/Dockerfile @@ -1,11 +1,17 @@ -FROM node:10.22.1-alpine3.11 as BUILD - -ENV VERSION=2.2.0 +ARG VERSION=2.2.0 +ARG PORTCHECKER_VERSION=v1.0.6 +ARG SCVERSION=v0.1.11 +FROM node:10.22.1-alpine3.11 as BUILD +ARG VERSION +ARG SCVERSION RUN apk add --no-cache --virtual .gyp libressl-dev git bash python make && \ -wget https://github.com/hackmdio/codimd/archive/$VERSION.tar.gz && \ -tar xzf $VERSION.tar.gz -C /opt && \ -mv /opt/codimd-$VERSION /opt/codimd + wget https://github.com/hackmdio/codimd/archive/${VERSION}.tar.gz && \ + tar xzf $VERSION.tar.gz -C /opt && \ + mv /opt/codimd-$VERSION /opt/codimd && \ + wget https://github.com/aptible/supercronic/releases/download/$SCVERSION/supercronic-linux-amd64 && \ + chmod +x supercronic-linux-amd64 && \ + mv supercronic-linux-amd64 /opt/codimd/supercronic RUN cd /opt/codimd && npm install && \ npm run build && \ @@ -17,15 +23,17 @@ RUN cd /opt/codimd && npm install && \ config.json.example README.md CONTRIBUTING.md AUTHORS node_modules FROM node:10.22.1-alpine3.11 - -RUN addgroup --gid 1500 codimd && \ - adduser -u 1500 -G codimd -D codimd && \ +ARG PORTCHECKER_VERSION +RUN addgroup --gid 5010 codimd && \ + adduser -u 5010 -G codimd -D codimd && \ mkdir /home/$USER_NAME/.npm && \ echo "prefix=/home/codimd/.npm/" > /home/$USER_NAME/.npmrc && \ - mkdir -p /home/codimd/app && \ + mkdir -p /home/codimd/app/deletedPads && \ chown -R codimd:codimd /home/codimd && \ - apk add --no-cache git bash python && \ - wget https://github.com/hackmdio/portchecker/releases/download/v1.0.5/portchecker-linux-amd64.tar.gz && \ + # Git needed so NPM can clone packages and Python for node-gyp + apk add --no-cache bash git python3-dev py3-pip gcc postgresql-dev musl-dev make && \ + pip3 install psycopg2 && \ + wget https://github.com/hackmdio/portchecker/releases/download/${PORTCHECKER_VERSION}/portchecker-linux-amd64.tar.gz && \ tar xvf portchecker-linux-amd64.tar.gz -C /usr/local/bin && \ mv /usr/local/bin/portchecker-linux-amd64 /usr/local/bin/pcheck && \ rm portchecker-linux-amd64.tar.gz @@ -34,10 +42,14 @@ USER codimd WORKDIR /home/codimd/app -COPY --chown=1500:1500 --from=BUILD /opt/codimd . +COPY --chown=5010:5010 --from=BUILD /opt/codimd . + +COPY --chown=5010:5010 deleteOldPad.py . RUN npm install --production && npm cache clean --force && rm -rf /tmp/{core-js-banners,phantomjs} +COPY entrypoint.sh . + EXPOSE 3000 -ENTRYPOINT ["/home/codimd/app/docker-entrypoint.sh"] +ENTRYPOINT ["./entrypoint.sh"] diff --git a/pica-codimd/README.md b/pica-codimd/README.md index 6b298cd43fdc0f24d9a7cde24ac9e0293120019e..17d828c5705bc2c5b3d9475f3f4c0dbd481b639e 100644 --- a/pica-codimd/README.md +++ b/pica-codimd/README.md @@ -2,13 +2,21 @@ `CodiMD` est un service de pad en markdown avec des fonctionnalités plus avancées qu'`Etherpad`. +Les fichiers proposés dans ce dossier permettent la création de comptes via l'email, la connexion OAuth2 sur l'instance Mattermost de Picasoft et l'édition anonyme de tous les pads. + ## Lancer une instance -Il faut commencer par cloner le dépôt `Dockerfiles` puis de se rendre dans le sous-dossier `pica-codimd`, enfin on lance `docker-compose up -d`. Ceci a pour effet de lancer un conteneur pour `CodiMD` et un autre de `PostgreSQL` pour stocker les données. +Copier les fichiers `.secrets.example` en `.secrets` et remplacer les valeurs. Les valeurs pour l'OAuth2 Mattermost peuvent se retrouver [ici](https://team.picasoft.net/picasoft/integrations/oauth2-apps). + +Depuis le sous-dossier `pica-codimd`, lancer `docker-compose up -d`. Ceci a pour effet de lancer un conteneur pour `CodiMD` et un autre de `PostgreSQL` pour stocker les données. + +## Configuration + +Elle s'effectue via l'environnement, dans le fichier Compose. Voir les valeurs disponibles ici : https://hackmd.io/s/codimd-configuration ## Mettre à jour -Pour mettre à jour l'image il suffit de modifier le fichier de fichier `Dockerfile` pour changer la valeur de l'argument `VERSION`. Il faut aussi penser à changer la valeur du tag dans le fichier `docker-compose.yml`. Ensuite il faut lancer le script `docker_test.sh` à la racine du dépôt. Une fois qu'on a vérifié que tout fonctionne bien on peut pousser l'image sur le registre et se rendre sur la machine de production pour lancer `docker-compose up -d`. +Pour mettre à jour l'image il suffit de modifier le fichier `Dockerfile` pour changer la valeur de l'argument `VERSION`. Il faut aussi penser à changer la valeur du tag dans le fichier `docker-compose.yml`. ## Supprimer un pad de la BDD diff --git a/pica-codimd/deleteOldPad.py b/pica-codimd/deleteOldPad.py new file mode 100755 index 0000000000000000000000000000000000000000..25991e12726119b96f65ab240ce877ab9cb0a69b --- /dev/null +++ b/pica-codimd/deleteOldPad.py @@ -0,0 +1,54 @@ +#! /usr/bin/python3 + +import psycopg2 +import sys +from os import environ + +INTERVAL = environ['OLD_INTERVAL'] +USER = environ['POSTGRES_USER'] +DATABASE = environ['POSTGRES_DB'] +PASSWORD = environ['POSTGRES_PASSWORD'] +HOST = environ['DB_HOST'] +PORT = environ['DB_PORT'] + +print("===== Begin of deleteOldPad job =====") + +#Connect to database +try: + db = psycopg2.connect("user = " + USER + " dbname = " +DATABASE + " password = " + PASSWORD + " host = " + HOST + " port = " + PORT) +except: + sys.exit("deleteOldPad : Unable to connect database") + +with db : + with db.cursor() as cur: + #Get all pads older than INTERVAL + try: + cur.execute("SELECT \"Notes\".\"id\", \"Notes\".\"content\" FROM \"Notes\" WHERE \"Notes\".\"updatedAt\" < NOW() - interval %s", (INTERVAL,)) + except: + sys.exit("deleteOldPad : unable to select old pads") + oldPads = cur.fetchall() + for oldPad in oldPads: + #Backup the pad + with open("deletedPads/" + oldPad[0] + '.txt', "w") as f: + f.write(oldPad[1]) + #Remove all Revisions related to this pad + try: + cur.execute("DELETE FROM \"Revisions\" WHERE \"Revisions\".\"noteId\" = %s", (oldPad[0],)) + except: + sys.exit("deleteOldPad : unable to delete all revisions related to pad " + oldPad[0]) + #Remove all contributions related to this pad + try: + cur.execute("DELETE FROM \"Authors\" WHERE \"Authors\".\"noteId\" = %s", (oldPad[0],)) + except: + sys.exit("deleteOldPad : unable to delete all contributions related to pad " + oldPad[0]) + #Remove the pad + try: + cur.execute("DELETE FROM \"Notes\" WHERE \"Notes\".\"id\" = %s", (oldPad[0],)) + except: + sys.exit("deleteOldPad : unable to delete the pad " + oldPad[0]) + + print("deleteOldPad : Deleted old pad") + +db.close() + +print("===== End of deleteOldPad job =====") diff --git a/pica-codimd/docker-compose.yml b/pica-codimd/docker-compose.yml index 78d60a73fbe5e17301a00f4d9dc43af3bdb70d09..0870bebee81a0621773eb3322680232d0183b82c 100644 --- a/pica-codimd/docker-compose.yml +++ b/pica-codimd/docker-compose.yml @@ -1,32 +1,56 @@ -version: '3' +version: '3.7' + +networks: + proxy: + external: true + codimd: + name: "codimd" + +volumes: + codimd-db: + name: 'codimd-db' + codimd-data: + name: 'codimd-data' + + services: codimd-db: - image: postgres:11.6-alpine + image: postgres:12-alpine container_name: codimd-db networks: - codimd volumes: - codimd-db:/var/lib/postrgresql/data - /etc/localtime:/etc/localtime:ro - env_file: ./secrets/codimd-db.secrets.example - restart: always + env_file: ./secrets/codimd-db.secrets + restart: unless-stopped codimd-app: - image: pica-codimd + image: registry.picasoft.net/pica-codimd:2.2.0 build: . container_name: codimd-app volumes: - codimd-data:/home/codimd/app/public/uploads depends_on: - codimd-db - env_file: ./secrets/codimd-db.secrets.example + env_file: ./secrets/codimd-db.secrets environment: - - CMD_USECDN=false - - CMD_DOMAIN=md.picasoft.net - - CMD_ALLOW_ANONYMOUS=true - - CMD_ALLOW_ANONYMOUS_EDITS=true - - CMD_PROTOCOL_USESSL=true - - CMD_CSP_ENABLE=false + CMD_USECDN: "false" + CMD_DOMAIN: md.picasoft.net + CMD_ALLOW_ANONYMOUS: "true" + CMD_ALLOW_ANONYMOUS_EDITS: "true" + CMD_ALLOW_PDF_EXPORT: "true" + CMD_PROTOCOL_USESSL: "true" + CMD_ALLOW_PDF_EXPORT: "true" + CMD_ALLOW_FREEURL: "true" + CMD_CSP_ENABLE: "false" + CMD_MATTERMOST_BASEURL: https://team.picasoft.net + CMD_DEFAULT_PERMISSION: freely + OLD_INTERVAL: "2 years" + DB_HOST: "codimd-db" + DB_PORT: 5432 + DELETE_AT: "0 0 * * *" + CMD_ALLOW_PDF_EXPORT: "false" networks: - proxy - codimd @@ -35,15 +59,4 @@ services: traefik.http.routers.codimd-app.rule: Host(`md.picasoft.net`) traefik.http.services.codimd-app.loadbalancer.server.port: 3000 traefik.enable: true - restart: always - -networks: - proxy: - external: true - codimd: - -volumes: - codimd-db: - external: true - codimd-data: - external: true + restart: unless-stopped diff --git a/pica-codimd/entrypoint.sh b/pica-codimd/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..e1d96d5d35f93a9da8897593d0768598d08b79f9 --- /dev/null +++ b/pica-codimd/entrypoint.sh @@ -0,0 +1,9 @@ +#! /bin/sh + +cat << EOF > /home/codimd/app/crontab +$DELETE_AT /home/codimd/app/deleteOldPad.py +EOF +sed "154a | <a href=\"https://picasoft.net/co/cgu.html\">CGU</a> " -i /home/codimd/app/public/views/index/body.ejs +sed "41a <span style=\"font-size:2em;font-weight:bold;\">Cette instance ne garde le contenu que deux ans après la dernière modification !</span>" -i /home/codimd/app/public/views/index/body.ejs +/home/codimd/app/docker-entrypoint.sh & +/home/codimd/app/supercronic /home/codimd/app/crontab diff --git a/pica-codimd/secrets/codimd-db.secrets.example b/pica-codimd/secrets/codimd-db.secrets.example index a986a290e6c04fdb63a6e588ca0bba83c9b928b1..afa2b26a7624894d900b22503e995b8158e4194e 100644 --- a/pica-codimd/secrets/codimd-db.secrets.example +++ b/pica-codimd/secrets/codimd-db.secrets.example @@ -2,4 +2,6 @@ POSTGRES_USER=codimd POSTGRES_PASSWORD=samepassword POSTGRES_DB=codimd CMD_DB_URL=postgres://codimd:samepassword@codimd-db/codimd -CMD_SESSION_SECRET=15dr0x3a7 +# See Mattermost → "Integrations" → "OAuth2" +CMD_MATTERMOST_CLIENTID= +CMD_MATTERMOST_CLIENTSECRET= diff --git a/pica-db-backup-rotation/config/backup_config.json b/pica-db-backup-rotation/config/backup_config.json index 7b5950cf81a9069d235a0afa1c220cef1bb17e43..5a5816a5b60f70df88d2a59b982291584c263476 100644 --- a/pica-db-backup-rotation/config/backup_config.json +++ b/pica-db-backup-rotation/config/backup_config.json @@ -43,5 +43,23 @@ "Week": 4, "Month": 12 } + }, + "mobilizon": { + "Folder": "mobilizon", + "Backup-Rota": { + "Hour": 24, + "Day": 7, + "Week": 4, + "Month": 12 + } + }, + "codimd": { + "Folder": "codimd", + "Backup-Rota": { + "Hour": 24, + "Day": 7, + "Week": 4, + "Month": 12 + } } } diff --git a/pica-db-backup/config/backup_config.json b/pica-db-backup/config/backup_config.json index daa635830228895b59dc881ab49bfc4e045af090..7db74b31c5755f5ec94390b087746055aea92d36 100644 --- a/pica-db-backup/config/backup_config.json +++ b/pica-db-backup/config/backup_config.json @@ -51,5 +51,27 @@ "Folder": "plume", "Cron": "0 1 * * *", "Init-Backup": "1" + }, + "mobilizon": { + "Host": "mobilizon-db", + "Port": "5432", + "User": "MOBILIZON_DB_USER", + "Password": "MOBILIZON_DB_PASSWORD", + "Database": "postgres_mobilizon", + "Type": "postgres", + "Folder": "mobilizon", + "Cron": "0 */6 * * *", + "Init-Backup": "1" + }, + "codimd": { + "Host": "codimd-db", + "Port": "5432", + "User": "CODIMD_DB_USER", + "Password": "CODIMD_DB_PASSWORD", + "Database": "codimd", + "Type": "postgres", + "Folder": "codimd", + "Cron": "0 */6 * * *", + "Init-Backup": "1" } } diff --git a/pica-db-backup/docker-compose.yml b/pica-db-backup/docker-compose.yml index fa14ae6a2b5e34e991f214e42017014905a5a800..33172e77eb44de635908c9492b68425938a906d8 100644 --- a/pica-db-backup/docker-compose.yml +++ b/pica-db-backup/docker-compose.yml @@ -9,6 +9,10 @@ networks: name: "plume" wekan: name: "wekan" + mobilizon: + name: "mobilizon" + codimd: + name: "codimd" services: db-backup: @@ -25,4 +29,6 @@ services: - etherpad_week - plume - wekan + - mobilizon + - codimd restart: unless-stopped diff --git a/pica-db-backup/secrets/db.secrets.example b/pica-db-backup/secrets/db.secrets.example index 97448640834fc58f562d73623447f19dc7b7b5e7..2aee4468e4a94d71f07ae676639ec9a1eac09d8d 100644 --- a/pica-db-backup/secrets/db.secrets.example +++ b/pica-db-backup/secrets/db.secrets.example @@ -6,3 +6,7 @@ BLOG_DB_USER= BLOG_DB_PASSWORD= ETHERPAD_WEEK_DB_USER= ETHERPAD_WEEK_DB_PASSWORD +MOBILIZON_DB_USER= +MOBILIZON_DB_PASSWORD= +CODIMD_DB_USER= +CODIMD_DB_PASSWORD= diff --git a/pica-etherpad/Dockerfile b/pica-etherpad/Dockerfile index d580806f51e201552b70edd7648298ecc7518594..1343f79e22e45d2e79d5732f3a1422baaa39921a 100644 --- a/pica-etherpad/Dockerfile +++ b/pica-etherpad/Dockerfile @@ -51,7 +51,7 @@ RUN curl -SL https://github.com/ether/etherpad-lite/archive/${ETHERPAD_VERSION_B COPY --chown=etherpad ./landing-page ./src/templates/landing-page # Build and replace landing page -RUN npm install minify@5 && \ +RUN npm install minify && \ ./src/templates/landing-page/build/build.sh && \ cp ./src/templates/landing-page/index.html src/templates/index.html && \ cp -r ./src/templates/landing-page/static/* src/static/ @@ -81,7 +81,7 @@ COPY --from=downloader /opt/etherpad-lite /opt/etherpad-lite/ # Install debian packages, as root USER root RUN apt-get update && \ - apt-get install -y curl nano postgresql-client && \ + apt-get install -y curl nano postgresql-client abiword && \ rm -rf /var/lib/apt/lists/* # Created folder for deleted pads diff --git a/pica-etherpad/docker-compose.yml b/pica-etherpad/docker-compose.yml index 692d370c39552bae1e0150de48954c14e917d9a5..ebf3a3346a6bfd920f8474bc12f4dc98a3ea8136 100755 --- a/pica-etherpad/docker-compose.yml +++ b/pica-etherpad/docker-compose.yml @@ -48,6 +48,7 @@ services: THEME: "colibris" TITLE: "Picapad" TRUST_PROXY: "true" + ABIWORD: "/usr/bin/abiword" networks: - proxy - standard @@ -89,6 +90,7 @@ services: THEME: "colibris" TITLE: "Picapad Hebdo" TRUST_PROXY: "true" + ABIWORD: "/usr/bin/abiword" depends_on: - etherpad-week-db networks: diff --git a/pica-etherpad/landing-page/build/build.sh b/pica-etherpad/landing-page/build/build.sh index da29221f3e6f423fe96757d6ce3309dd489d677d..ca8d937c81797027b9bfcc7ad339e6d6ed99b76e 100755 --- a/pica-etherpad/landing-page/build/build.sh +++ b/pica-etherpad/landing-page/build/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # Requirements: # @@ -11,64 +11,14 @@ set -e # Change directory to the parent folder of this script -source_dir="$( dirname "${BASH_SOURCE[0]}" )" +source_dir="$( dirname $0 )" cd "$source_dir" -# Search dependencies - -NPM=$(command -v npm) || true -OPTIPNG=$(command -v optipng) || true -JPEGOPTIM=$(command -v jpegoptim) || true -MINIFY=$(command -v minify) || true - -if [ ! $MINIFY ]; then - MINIFY=$(command -v minify.js) || true -fi - -if [ -f /opt/etherpad-lite/node_modules/minify/bin/minify.js ]; then - MINIFY="/opt/etherpad-lite/node_modules/minify/bin/minify.js" -fi - -# If there are missing dependencies, print install instructions - -if [[ ! $OPTIPNG || ! $JPEGOPTIM || ! $NPM || ! $MINIFY ]]; then - - echo -e "\nError: The following dependencies are missing:\n" - - if [ ! $OPTIPNG ]; then - echo "\t* 'optipng'" - install_list="optipng" - fi - if [ ! $JPEGOPTIM ]; then - echo "\t* 'jpegoptim'" - install_list="$install_list jpegoptim" - fi - if [ ! $NPM ]; then - echo "\t* 'npm'" - install_list="$install_list npm" - fi - if [ ! $MINIFY ]; then - echo "\t* node package 'minify'" - fi - - echo -e "\nIf you are on Fedora, you can install missing dependencies by running:\n" - - if [ $install_list ]; then - echo "\$ sudo dnf install $install_list" - fi - if [ ! $MINIFY ]; then - echo "\$ npm install minify" - echo -e "\nDon't forget to add ./node_modules/minify/bin/ to your PATH in ~/.bashrc\n" - fi - - exit 1 - -fi - +MINIFY="/opt/etherpad-lite/node_modules/.bin/minify" # Minify a file in the format name.extension to name.min.extension # Usage: minify_file <path_to_file_without_extension> <extension> -function minify_file { +minify_file() { if [ -f $1.$2 ]; then echo -n "Minifying '$1.$2' ... " cat $1.$2 | $MINIFY --$2 > $1.min.$2 && echo "OK." @@ -77,7 +27,7 @@ function minify_file { fi } -function echo_blue { +echo_blue() { echo -e "\033[1;34m\n$1\n\033[0m" } diff --git a/pica-etherpad/landing-page/static/img/picasoft_logo_pad.png b/pica-etherpad/landing-page/static/img/picasoft_logo_pad.png index 8cd21d399d204d8e14e1fe76d9010aecb2391863..132f7631e47589c4944ccca9f2e3f11bd16267ef 100644 Binary files a/pica-etherpad/landing-page/static/img/picasoft_logo_pad.png and b/pica-etherpad/landing-page/static/img/picasoft_logo_pad.png differ diff --git a/pica-grafana-prom/prometheus.yml b/pica-grafana-prom/prometheus.yml index 1d2695083dda5a24fb162ba5c73896bbed02382b..04817700e6c32a6f78aa6d1b6218f8d103a2906b 100644 --- a/pica-grafana-prom/prometheus.yml +++ b/pica-grafana-prom/prometheus.yml @@ -34,3 +34,12 @@ scrape_configs: static_configs: - targets: - 'voice.picasoft.net' + - job_name: codimd + honor_timestamps: true + scrape_interval: 5s + scrape_timeout: 5s + metrics_path: '/metrics/codimd' + scheme: 'https' + static_configs: + - targets: + - 'md.picasoft.net' diff --git a/pica-graphbot/Dockerfile b/pica-graphbot/Dockerfile index c5f26012db31ba2710d1675fdbe611a83f695a8a..5d36ff5fdf816b3654b511450282732c1acc5792 100644 --- a/pica-graphbot/Dockerfile +++ b/pica-graphbot/Dockerfile @@ -1,4 +1,4 @@ -FROM chosto/graphbot:v1.4.2 +FROM chosto/graphbot:v1.4.3 COPY ./inject_env.sh /inject_env.sh CMD [ "/inject_env.sh" ] diff --git a/pica-graphbot/config.json b/pica-graphbot/config.json index e984a254cae25a0dcb08ed1a323045e84b74f58a..18b7fc45b004c4c8e801a464e44ba637f44a5394 100644 --- a/pica-graphbot/config.json +++ b/pica-graphbot/config.json @@ -28,19 +28,6 @@ "key": "auth/pica02/key.pem" } }, - { - "name": "pica01-test", - "url": "pica01-test.picasoft.net", - "port": 2376, - "exclude": [], - "default_network": "proxy", - "tls_config": - { - "ca_cert": "auth/pica01-test/ca.pem", - "cert": "auth/pica01-test/cert.pem", - "key": "auth/pica01-test/key.pem" - } - }, { "name": "monitoring", "url": "localhost", diff --git a/pica-graphbot/docker-compose.yml b/pica-graphbot/docker-compose.yml index 648b5c71b878f4ed58c3d5e95f7370b1c3e2f5c8..0f00367a741b246fdb7da504717d1261a7908c31 100644 --- a/pica-graphbot/docker-compose.yml +++ b/pica-graphbot/docker-compose.yml @@ -9,7 +9,7 @@ volumes: services: app: - image: registry.picasoft.net/graph-bot:v1.4.2 + image: registry.picasoft.net/graph-bot:v1.4.3 container_name: graph-bot build: . init: true diff --git a/pica-lufi/Dockerfile b/pica-lufi/Dockerfile index 44374aab89f73e6970b7e171071a24689ab5c292..0f3dc4130296062bbc73b7fe2cbfa0b8443d0972 100644 --- a/pica-lufi/Dockerfile +++ b/pica-lufi/Dockerfile @@ -1,6 +1,6 @@ FROM debian:buster -ARG LUFI_BUILD_VERSION=0.05.5 +ARG LUFI_BUILD_VERSION=fix-209-cannot-send-mail ENV APP_HOME=/lufi # Install dependencies @@ -21,8 +21,11 @@ RUN wget "$SUPERCRONIC_URL" \ && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic # Get Lufi release -RUN wget https://framagit.org/fiat-tux/hat-softwares/lufi/-/releases/${LUFI_BUILD_VERSION}.zip && unzip ${LUFI_BUILD_VERSION}.zip \ -&& rm ${LUFI_BUILD_VERSION}.zip && mv lufi-${LUFI_BUILD_VERSION} lufi +# RUN wget https://framagit.org/fiat-tux/hat-softwares/lufi/-/releases/${LUFI_BUILD_VERSION}.zip \ +RUN wget -O ${LUFI_BUILD_VERSION}.zip https://framagit.org/fiat-tux/hat-softwares/lufi/-/archive/${LUFI_BUILD_VERSION}/lufi-${LUFI_BUILD_VERSION}.zip \ +&& unzip ${LUFI_BUILD_VERSION}.zip \ +&& rm ${LUFI_BUILD_VERSION}.zip \ +&& mv lufi-${LUFI_BUILD_VERSION} lufi WORKDIR ${APP_HOME} diff --git a/pica-lufi/README.md b/pica-lufi/README.md index 81185f0223c60a2467348fca4bf708d6336a9a58..03bb9be4f0f72c03ecefc7515aae04cfcf752822 100644 --- a/pica-lufi/README.md +++ b/pica-lufi/README.md @@ -10,12 +10,31 @@ Il peut recevoir des variables d'environnement avec la syntaxe suivante : `$ENV[ Le thème est injecté directement dans l'image à partir du dossier [picadrop](./picadrop). Il ne contient pas de modifications esthétiques pour le moment, juste une modification des URL (CGU...). +### Premier lancement + +Copier les fichiers de secrets en enlevant le `.example` et remplacer les valeurs. + +Vérifier que le dossier correspondant au `device` de `lufi-data` existe sur l'hôte et que le propriétaire est bien l'utilisateur correspondant à Lufi dans le LDAP. + +Exemple pour un `device` qui vaut `/DATA/docker/lufi` et un utilisateur avec l'UID `5002` et le GID `502` (valeurs actuelles dans le LDAP) : + +```bash +$ sudo chown -R 5002:502 /DATA/lufi +``` + +Ce dossier doit être stocké sur un disque dur et non sur un SSD, en bout de chaîne. Voir [cette documentation](https://wiki.picasoft.net/doku.php?id=technique:docker:good_practices:storage#cas_particulier). + ### Lancement -Copier les fichiers de secrets en enlevant le `.example` et lancer le fichier Compose. +```bash +docker-compose up -d +``` ### Mise à jour +Jusqu'à ce que [cette issue](https://framagit.org/fiat-tux/hat-softwares/lufi/-/issues/209#note_793653) soit fermée, la branche `fix-209-cannot-send-mail` est utilisée. +Une fois qu'elle sera fermée, on pourra utiliser les numéros de release comme indiqué ci dessous. Il faudra changer l'URL de téléchargement dans le `Dockerfile` en décommentant le `wget` et en enlevant l'actuel. + Il suffit de changer `LUFI_BUILD_VERSION` dans le `Dockerfile` et de reconstruire l'image. Aucune autre opération n'est nécessaire pour effectuer les migrations et relancer le service. diff --git a/pica-lufi/docker-compose.yml b/pica-lufi/docker-compose.yml index 9cfd2878134844762ef20cb85caad81f7f7eb7f5..ddc2cf1c3977b9f1359c4f9b8562581e7f27f5e6 100644 --- a/pica-lufi/docker-compose.yml +++ b/pica-lufi/docker-compose.yml @@ -2,8 +2,16 @@ version: "3.7" volumes: lufidb-data: - lufi-data: + name: lufidb-data lufi-files: + driver: local + driver_opts: + type: bind + device: /DATA/docker/lufi + o: bind + name: lufi-files + lufi-data: + name: lufi-data networks: proxy: @@ -12,7 +20,7 @@ networks: services: lufi: - image: registry.picasoft.net/lufi:0.05.2 + image: registry.picasoft.net/lufi:fix-mail build: . container_name: lufi depends_on: diff --git a/pica-lufi/entrypoint.sh b/pica-lufi/entrypoint.sh index be4b9a036443e5cae8d9515ed0a4c03a61419f2b..ffdc6ecfd458f996650a91b8cd1c9023f64e17e8 100644 --- a/pica-lufi/entrypoint.sh +++ b/pica-lufi/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash if [ -z "${EMAIL_PASSWORD}" ]; then echo "EMAIL_PASSWORD not set, exiting!" diff --git a/pica-lufi/lufi.conf b/pica-lufi/lufi.conf index 47648a5f3f35607b0ced37f7ab5ac0787a885043..b2bec848d04595ec754215329ed6e0e70ab6907a 100644 --- a/pica-lufi/lufi.conf +++ b/pica-lufi/lufi.conf @@ -139,12 +139,12 @@ mail => { # Valid values are 'sendmail' and 'smtp' how => 'smtp', - owargs => { host => 'mail.picasoft.net', ssl => 'starttls', sasl_username => 'drop', sasl_password => $ENV{'EMAIL_PASSWORD'}, helo => 'drop.test.picasoft.net'} + howargs => { host => 'mail.picasoft.net', ssl => 'starttls', sasl_username => 'drop', sasl_password => $ENV{'EMAIL_PASSWORD'}, helo => 'drop.picasoft.net'} }, # Email sender address # optional, default to no-reply@lufi.io - mail_sender => 'drop@picasoft.net' + mail_sender => 'drop@picasoft.net', ############# # DB settings diff --git a/pica-lufi/picadrop/public/img/favicon.png b/pica-lufi/picadrop/public/img/favicon.png index cca7511494ee23c860c7886728009beb9be8fb35..07d1101d99afc0fc0f73474888ce305aba1e609d 100644 Binary files a/pica-lufi/picadrop/public/img/favicon.png and b/pica-lufi/picadrop/public/img/favicon.png differ diff --git a/pica-lufi/picadrop/public/img/lufi-min.png b/pica-lufi/picadrop/public/img/lufi-min.png index 396b277624a2ecb8dddade0282dbe18ca2804487..99fedba6f266535d27300b6a7b9b91c9a23ae72c 100644 Binary files a/pica-lufi/picadrop/public/img/lufi-min.png and b/pica-lufi/picadrop/public/img/lufi-min.png differ diff --git a/pica-lufi/picadrop/public/img/lufi.png b/pica-lufi/picadrop/public/img/lufi.png index cca7511494ee23c860c7886728009beb9be8fb35..07d1101d99afc0fc0f73474888ce305aba1e609d 100644 Binary files a/pica-lufi/picadrop/public/img/lufi.png and b/pica-lufi/picadrop/public/img/lufi.png differ diff --git a/pica-lufi/picadrop/public/img/lufi120.png b/pica-lufi/picadrop/public/img/lufi120.png index 93e0c2b00422c5c1589ffba41a452b5d27545ad5..c87fe5a8bf56a9b5504b7296c09b9d192d2bbd6c 100644 Binary files a/pica-lufi/picadrop/public/img/lufi120.png and b/pica-lufi/picadrop/public/img/lufi120.png differ diff --git a/pica-lufi/picadrop/public/img/lufi128.png b/pica-lufi/picadrop/public/img/lufi128.png index c227b98ee440585b45bd579100db9932456a9652..a9ad935562f4fdc366f77d158fade20d0e5685d0 100644 Binary files a/pica-lufi/picadrop/public/img/lufi128.png and b/pica-lufi/picadrop/public/img/lufi128.png differ diff --git a/pica-lufi/picadrop/public/img/lufi152.png b/pica-lufi/picadrop/public/img/lufi152.png index 5a960e1ce33c869e0864f919952dddc7fa859997..14f6c23c9f5c6558a5b98f5ee4b1a3728c7f4c8b 100644 Binary files a/pica-lufi/picadrop/public/img/lufi152.png and b/pica-lufi/picadrop/public/img/lufi152.png differ diff --git a/pica-lufi/picadrop/public/img/lufi196.png b/pica-lufi/picadrop/public/img/lufi196.png index 0e57e092246662d8492f7d614bd72982fb93bdc8..c41b1873e1ea10cf08994773f52d6214d4417c0d 100644 Binary files a/pica-lufi/picadrop/public/img/lufi196.png and b/pica-lufi/picadrop/public/img/lufi196.png differ diff --git a/pica-lufi/picadrop/public/img/lufi60.png b/pica-lufi/picadrop/public/img/lufi60.png index 5d65ffb4a41c128ac65ad081a043700a1388825c..807fc483304b5f9c275b9b85271d4b87005cf861 100644 Binary files a/pica-lufi/picadrop/public/img/lufi60.png and b/pica-lufi/picadrop/public/img/lufi60.png differ diff --git a/pica-lufi/picadrop/public/img/lufi76.png b/pica-lufi/picadrop/public/img/lufi76.png index b2aceecf1fc842f268ce36286c712b40b3f46a2d..f4f5c979dbc37812e2156c28098014dda39a6efb 100644 Binary files a/pica-lufi/picadrop/public/img/lufi76.png and b/pica-lufi/picadrop/public/img/lufi76.png differ diff --git a/pica-lufi/picadrop/public/img/lufi_favicon.png b/pica-lufi/picadrop/public/img/lufi_favicon.png index cca7511494ee23c860c7886728009beb9be8fb35..07d1101d99afc0fc0f73474888ce305aba1e609d 100644 Binary files a/pica-lufi/picadrop/public/img/lufi_favicon.png and b/pica-lufi/picadrop/public/img/lufi_favicon.png differ diff --git a/pica-mobilizon/README.md b/pica-mobilizon/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8e72dcd582f39414f332e32c0cdbab3783144e1a --- /dev/null +++ b/pica-mobilizon/README.md @@ -0,0 +1,39 @@ +## Mobilizon + +[[_TOC_]] + +### Introduction + +Au moment où cette configuration Docker a été réalisée (avant la `1.0.0`), il n'existait pas de Dockerfile officiel. Ce dossier est inspiré de la configuration proposée par l'utilisateur [Windyo de Framagit](https://framagit.org/Windyo/mobilizon/-/blob/a1e0b9730e9c63de6058c3f5d803b2743efafed4/docker), avec quelques adaptations pour Picasoft. + +Peu de temps après la sortie de la version `1.0.0`, un `Dockerfile` et un `docker-compose.yml` officiels ont été ajoutés au [dépôt git de Mobilizon](https://framagit.org/framasoft/mobilizon/-/tree/master/docker/production), et l'image docker principale sur le [hub de docker.com](https://hub.docker.com/r/framasoft/mobilizon/tags). Les instructions d'utilisation sont disponible dans la [doc de Mobilizon](https://docs.joinmobilizon.org/administration/docker/). Il peut être utile dans le futur pour des raisons de maintenance de passer sur cette configuration. + +### Procédure de mise-à -jour + +Pour changer la version de Mobilizon, il suffit de modifier la valeur de la variable `MOBILIZON_GIT_TAG` du [`docker-compose.yml`](./docker-compose.yml) par la version souhaitée. Les valeurs suivantes sont possibles : +- [Nom d'une release](https://framagit.org/framasoft/mobilizon/-/releases) +- Nom d'une branche +- Identifiant d'un commit + +Pour changer la version de Postgres, Postgis ou d'Elixir, se reporter aux `Dockerfile` correspondants. Une attention particulière doit être portée sur la compatibilité des 2 premiers avec les données persistées. + +Une fois les valeurs changées, il ne faut pas oublier de reconstruire les images si nécessaire. Ce processus prend environ 20 minutes. + +### Commandes en console utiles + +**Attention : toute commande `Elixir` doit être précédée de `MIX_ENV=prod` pour pouvoir s'exécuter proprement !** + +#### Ajout d'un utilisateur avec les droits admin ou modérateur + +Actuellement, il n'est pas possible de créer un compte administrateur ou modérateur depuis l'interface web, il est nécessaire de d'exécuter la commande suivante dans le conteneur `mobilizon-app` : +``` +MIX_ENV=prod mix mobilizon.users.new email@host.pica --admin --password notS0Secre1Passwd +``` +ou (exclusif) +``` +MIX_ENV=prod mix mobilizon.users.new email@host.pica --moderator --password notS0Secre1Passwd +``` + +#### Modification d'un utilisateur + +Pour modifier le rôle d'un utilisateur déjà existant, se reporter à la [commande `mobilizon.users.modify`](https://framagit.org/framasoft/mobilizon/-/blob/master/lib/mix/tasks/mobilizon/users/modify.ex). \ No newline at end of file diff --git a/pica-mobilizon/app/Dockerfile b/pica-mobilizon/app/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..8dcd1c21234ce0cf3157f2ac12f1b0cea5266064 --- /dev/null +++ b/pica-mobilizon/app/Dockerfile @@ -0,0 +1,55 @@ +# inspired from https://framagit.org/Windyo/mobilizon/-/blob/a1e0b9730e9c63de6058c3f5d803b2743efafed4/docker/app/Dockerfile + +# **** Temporary docker image **** +# elixir version MUST match +FROM elixir:1.10.4 as builder +ARG MOBILIZON_GIT_URL +ARG MOBILIZON_GIT_TAG +ARG NODE_V +ENV MIX_ENV prod +ENV INSTANCE_CONFIG prod +RUN apt-get update -y \ + && apt-get install -y apt-utils \ + && curl -sL https://deb.nodesource.com/setup_"$NODE_V".x | bash - \ + && apt-get install -y nodejs build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 python3-pip cmake \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && npm install -g yarn wait-on +RUN useradd -ms /bin/bash -p ! mobilizon +USER mobilizon +WORKDIR /home/mobilizon +RUN git clone -b "$MOBILIZON_GIT_TAG" "$MOBILIZON_GIT_URL" ./build +WORKDIR /home/mobilizon/build +COPY ./prod.secret.exs /home/mobilizon/build/config/ +RUN mix local.hex --force \ + && mix local.rebar --force +RUN mix deps.get +RUN mix deps.compile +RUN mix compile +WORKDIR /home/mobilizon/build/js +RUN yarn install \ + && yarn run build +WORKDIR /home/mobilizon/build +RUN rm -rf ./.dockerignore ./.gitignore ./.gitlab-ci.yml ./CHANGELOG.md ./CONTRIBUTING.md ./docker ./docker-compose.test.yml ./docker-compose.yml ./Dockerfile ./docs ./js ./Makefile ./README.md ./SECURITY.md ./setup_db.psql ./support \ + && curl https://dbip.mirror.framasoft.org/files/dbip-city-lite-latest.mmdb --output GeoLite2-City.mmdb -s \ + && mv GeoLite2-City.mmdb /home/mobilizon/build/priv/data/GeoLite2-City.mmdb + +# Final docker image +FROM elixir:1.10.4-slim +ENV INIT=FALSE \ + ADMIN_EMAIL=test@test.com \ + ADMIN_PASSWORD=passwd \ + MIX_ENV=prod \ + INSTANCE_CONFIG=prod +RUN useradd -ms /bin/bash -p ! mobilizon \ + && apt-get update \ + && apt-get install -y git file\ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +COPY --from=builder /home/mobilizon/build/ /home/mobilizon/live/ +COPY --from=builder /home/mobilizon/.mix/ /home/mobilizon/.mix/ +COPY ./entrypoint.sh /home/mobilizon/entrypoint.sh +RUN chmod +x /home/mobilizon/entrypoint.sh +WORKDIR /home/mobilizon/live +USER mobilizon +ENTRYPOINT [ "/home/mobilizon/entrypoint.sh" ] diff --git a/pica-mobilizon/app/entrypoint.sh b/pica-mobilizon/app/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..b8245708da86f7ede2f47b6522997d5eaad40d78 --- /dev/null +++ b/pica-mobilizon/app/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +export MIX_ENV=prod +if [ "$INIT" = TRUE ]; then + echo "Initialization. Only run this once." + mix ecto.migrate + mix mobilizon.users.new "$ADMIN_EMAIL" --admin --password "$ADMIN_PASSWORD" + mix phx.server +else + echo "Running normal mode." + mix ecto.migrate --no-deps-check + mix phx.server --no-deps-check +fi + +exec "$@" diff --git a/pica-mobilizon/app/prod.secret.exs b/pica-mobilizon/app/prod.secret.exs new file mode 100644 index 0000000000000000000000000000000000000000..a653f5589b5aa7f8b6b60597fd57b940ef31afcb --- /dev/null +++ b/pica-mobilizon/app/prod.secret.exs @@ -0,0 +1,52 @@ +# Mobilizon instance configuration +# Via Thomas Clavier + +# Warning : cfg is overrided by the ../docker-compose.yml and ../secrets/*.secrets files + +import Config + +config :mobilizon, Mobilizon.Web.Endpoint, + url: [host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan")], + http: [port: System.get_env("MOBILIZON_INSTANCE_LISTEN_PORT", "4000")], + secret_key_base: System.get_env("MOBILIZON_SECRET_KEY_BASE", "ZcvexeC7cnwtKR8ADMBDwrYu2aYHUyjrOu4yA181Z112HNu/I5jyRleo4hoxOMqQ") + +config :mobilizon, Mobilizon.Web.Auth.Guardian, + secret_key: System.get_env("MOBILIZON_SECRET_KEY", "KsdUIvp6hQ7b97yxUZcDQyGH0g4LS3fF0OvIsIATpkKzd1MDvSS4KexWXsjXeMQZ") + +config :mobilizon, :instance, + name: System.get_env("MOBILIZON_INSTANCE_NAME", "Mobilizon"), + description: "Change this to a proper description of your instance", + hostname: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan"), + registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN", "false"), + demo: false, + allow_relay: true, + federating: true, + email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL", "noreply@mobilizon.lan"), + email_reply_to: System.get_env("MOBILIZON_INSTANCE_EMAIL", "noreply@mobilizon.lan") + +config :mobilizon, Mobilizon.Storage.Repo, + adapter: Ecto.Adapters.Postgres, + username: System.get_env("MOBILIZON_DATABASE_USERNAME", "username"), + password: System.get_env("MOBILIZON_DATABASE_PASSWORD", "password"), + database: System.get_env("MOBILIZON_DATABASE_DBNAME", "mobilizon"), + hostname: System.get_env("MOBILIZON_DATABASE_HOST", "postgres"), + port: System.get_env("MOBILIZON_DATABASE_PORT", "5432"), + pool_size: 10 + +config :mobilizon, Mobilizon.Web.Email.Mailer, + adapter: Bamboo.SMTPAdapter, + server: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"), + hostname: System.get_env("MOBILIZON_SMTP_HOSTNAME", "localhost"), + port: System.get_env("MOBILIZON_SMTP_PORT", "25"), + username: System.get_env("MOBILIZON_SMTP_USERNAME", nil), + password: System.get_env("MOBILIZON_SMTP_PASSWORD", nil), + # can be `:always` or `:never` + tls: :if_available, + allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2", :"tlsv1.3"], + # can be `true` + ssl: System.get_env("MOBILIZON_SMTP_SSL", "false"), + retries: 1, + # can be `true` + no_mx_lookups: false, + # can be `:if_available`. If your smtp relay requires authentication set it to `:always`. + auth: :always diff --git a/pica-mobilizon/db/Dockerfile b/pica-mobilizon/db/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..01800da65b9d967608bc1421757d56cf1f9a5e8f --- /dev/null +++ b/pica-mobilizon/db/Dockerfile @@ -0,0 +1,5 @@ +# Same Dockerfile as official image, but different extensions : +# https://github.com/postgis/docker-postgis/blob/7639baab95220201b87476b2dd09e011423ebd55/12-3.0/alpine/initdb-postgis.sh +FROM postgis/postgis:12-3.0-alpine + +COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh diff --git a/pica-mobilizon/db/initdb-postgis.sh b/pica-mobilizon/db/initdb-postgis.sh new file mode 100644 index 0000000000000000000000000000000000000000..6a716a6fa7c61eafbaa3d1ee224b42e18bce7d26 --- /dev/null +++ b/pica-mobilizon/db/initdb-postgis.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +# Perform all actions as $POSTGRES_USER +export PGUSER="$POSTGRES_USER" + +# Create the 'template_postgis' template db +"${psql[@]}" <<- 'EOSQL' +CREATE DATABASE template_postgis IS_TEMPLATE true; +EOSQL + +# Load PostGIS into both template_database and $POSTGRES_DB +for DB in template_postgis "$POSTGRES_DB"; do + echo "Loading PostGIS extensions into $DB" + "${psql[@]}" --dbname="$DB" <<-'EOSQL' + CREATE EXTENSION IF NOT EXISTS postgis; + CREATE EXTENSION IF NOT EXISTS pg_trgm; + CREATE EXTENSION IF NOT EXISTS unaccent; +EOSQL +done diff --git a/pica-mobilizon/docker-compose.yml b/pica-mobilizon/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..aac17f051e686aa5859aa073e51f65e7d22df59e --- /dev/null +++ b/pica-mobilizon/docker-compose.yml @@ -0,0 +1,74 @@ +# inspired from https://framagit.org/Windyo/mobilizon/-/blob/a1e0b9730e9c63de6058c3f5d803b2743efafed4/docker/docker-compose.yml + +version: "3.7" + +networks: + proxy: + external: true + mobilizon: + name: "mobilizon" + +volumes: + mobilizon-data: + name: mobilizon-data + mobilizon-db: + name: mobilizon-db + +services: + mobilizon: + image: registry.picasoft.net/pica-mobilizon:1.0.0 + build: + context: ./app + dockerfile: Dockerfile + args: + - NODE_V=14 + - MOBILIZON_GIT_URL=https://framagit.org/framasoft/mobilizon.git + - MOBILIZON_GIT_TAG=1.0.0 + - MIX_ENV=prod + container_name: mobilizon-app + volumes: + - mobilizon-data:/app + - /etc/localtime:/etc/localtime:ro + environment: + - MIX_ENV=prod + # setup the instance config + - MOBILIZON_INSTANCE_HOST=mobilizon.picasoft.net + - MOBILIZON_INSTANCE_NAME=Instance Mobilizon de Picasoft + - MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=true + - MOBILIZON_INSTANCE_EMAIL=mobilizon@picasoft.net + - MOBILIZON_DATABASE_HOST=mobilizon-db + # standard ports, don't really need changing + - MOBILIZON_DATABASE_PORT=5432 + - MOBILIZON_INSTANCE_LISTEN_PORT=4000 + env_file: + - ./secrets/mobilizon-db.secrets + - ./secrets/mobilizon-app.secrets + labels: + traefik.enable: true + traefik.http.routers.mobilizon-app.entrypoints: websecure + traefik.http.routers.mobilizon-app.rule: Host(`mobilizon.picasoft.net`) + traefik.http.services.mobilizon-app.loadbalancer.server.port: 4000 + networks: + - proxy + - mobilizon + depends_on: + - mobilizon-db + restart: unless-stopped + + mobilizon-db: + image: registry.picasoft.net/pica-postgres-postgis:12-alpine + build: + context: ./db + dockerfile: Dockerfile + args: + - POSTGRES_DB=postgres_mobilizon + container_name: mobilizon-db + volumes: + - mobilizon-db:/var/lib/postgresql/data + - /etc/localtime:/etc/localtime:ro + env_file: + - ./secrets/mobilizon-db.secrets + networks: + - mobilizon + restart: unless-stopped + diff --git a/pica-mobilizon/secrets/mobilizon-app.secrets.example b/pica-mobilizon/secrets/mobilizon-app.secrets.example new file mode 100644 index 0000000000000000000000000000000000000000..468c18486b1fc93491a8a3a098aac768bdf178c5 --- /dev/null +++ b/pica-mobilizon/secrets/mobilizon-app.secrets.example @@ -0,0 +1,9 @@ +INIT=FALSE +ADMIN_EMAIL=your@email.com +ADMIN_PASSWORD=yourpasswordtologin +MOBILIZON_SMTP_SERVER=host.fr +MOBILIZON_SMTP_HOSTNAME=your.host.fr +MOBILIZON_SMTP_PORT=25 +MOBILIZON_SMTP_USERNAME=your@email.com +MOBILIZON_SMTP_PASSWORD=yourpasswordtologin +MOBILIZON_SMTP_SSL=false diff --git a/pica-mobilizon/secrets/mobilizon-db.secrets.example b/pica-mobilizon/secrets/mobilizon-db.secrets.example new file mode 100644 index 0000000000000000000000000000000000000000..d9d43fd004c4229f7e848e8a1bd663610c7ee02c --- /dev/null +++ b/pica-mobilizon/secrets/mobilizon-db.secrets.example @@ -0,0 +1,6 @@ +POSTGRES_DB=postgres_mobilizon +POSTGRES_USER=mobilizon +POSTGRES_PASSWORD=superSecretPsswrd +MOBILIZON_DATABASE_DBNAME=postgres_mobilizon +MOBILIZON_DATABASE_USERNAME=mobilizon +MOBILIZON_DATABASE_PASSWORD=superSecretPsswrd diff --git a/pica-whiteboard/Dockerfile b/pica-whiteboard/Dockerfile index 9ca876f72d11714592b0b8018ad3edd2b56fab70..10c3053996addbf561488bbba56c1d35df11c726 100644 --- a/pica-whiteboard/Dockerfile +++ b/pica-whiteboard/Dockerfile @@ -1,25 +1,31 @@ FROM node:14.2.0-alpine3.11 ENV WBVERSION=1.5 \ - SCVERSION=0.1.9 + SCVERSION=0.1.11 -RUN mkdir -p /opt/app && \ - apk add --no-cache --virtual .download ca-certificates wget && \ +RUN apk add --no-cache --virtual .download ca-certificates wget && \ + apk add --no-cache nginx && \ + mkdir /run/nginx && touch /run/nginx/nginx.pid && \ wget https://github.com/cracker0dks/whiteboard/archive/v$WBVERSION.tar.gz && \ wget https://github.com/aptible/supercronic/releases/download/v$SCVERSION/supercronic-linux-amd64 && \ chmod +x supercronic-linux-amd64 && \ mv supercronic-linux-amd64 /usr/local/bin/supercronic && \ - tar -C /opt/app -xzf v$WBVERSION.tar.gz && \ + tar -C /opt -xzvf v$WBVERSION.tar.gz && \ rm v$WBVERSION.tar.gz && \ - cd /opt/app/whiteboard-$WBVERSION && \ + mv /opt/whiteboard-$WBVERSION /opt/whiteboard && \ + cd /opt/whiteboard && \ npm ci && \ apk del .download -ADD crontab /opt/app/whiteboard-$WBVERSION/crontab -ADD entrypoint.sh /entrypoint.sh +ADD entrypoint.sh /entrypoint.sh +ADD default.conf /etc/nginx/conf.d/default.conf +ADD index.html /var/www/localhost/htdocs/index.html +ADD picasoft.svg /var/www/localhost/htdocs/picasoft.svg +ADD picasoft-logo-whiteboard.png /var/www/localhost/htdocs/picasoft-logo-whiteboard.png +ADD default.css /var/www/localhost/htdocs/default.css RUN chmod +x /entrypoint.sh -EXPOSE 8080 +EXPOSE 80 ENTRYPOINT ["/entrypoint.sh"] diff --git a/pica-whiteboard/default.conf b/pica-whiteboard/default.conf new file mode 100644 index 0000000000000000000000000000000000000000..489d4eb77d291fb088b63e0ca57d14bc1d2d10e5 --- /dev/null +++ b/pica-whiteboard/default.conf @@ -0,0 +1,22 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + + root /var/www/localhost/htdocs; + + index index.html; + + location / { + try_files $uri $uri/ =404; + } + + location /app/ { + proxy_pass http://whiteboard-app:8080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection upgrade; + } +} diff --git a/pica-whiteboard/default.css b/pica-whiteboard/default.css new file mode 100644 index 0000000000000000000000000000000000000000..8be587f49e8076aad332b8970fec2637957261af --- /dev/null +++ b/pica-whiteboard/default.css @@ -0,0 +1,154 @@ +/* INIT */ +*{ + margin: 0; + box-sizing: border-box; + font-family: 'Lato', 'Helvetica Neue', Helvetica, Arial, sans-serif; + text-align: center; +} + +:root { + --background: #303030; + --background-darker: #272727; + --background-lighter: #333333; + --background-header: #18684D; + --background-warning: #8C2424; + --color: #DDDDDD; +} + +.flex-center-column { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.flex-row-spacearound { + display: flex; + width: 100%; + justify-content: space-around; +} + +.margin-small { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +.margin-medium { + margin-top: 1em; + margin-bottom: 1em; +} + +.margin-big { + margin-top: 4em; + margin-bottom: 4em; +} + +/* SPECIFIC */ + +body{ + background-color: var(--background); + color: var(--color); + font-size: 1.2em; +} + +header{ + background-color: var(--background-header); + padding: 5px; + padding-top: 10px; +} + +header h1{ + display: inline; +} + +article{ + width: 100%; +} + +.logo{ + width: 9em; +} + +.main-center{ + width: 85%; + max-width: 640px; +} + +.warning{ + padding: 15px; + background-color: var(--background-warning); + border-radius: 10px; +} + +input[type="text"]{ + border: none; + border-radius: 5px; + width: 100%; + height: 3em; +} + +.buttons * { + padding: 20px; + color: var(--color); + font-size: 1em; + background-color: #075C7B; + width: 11em; + max-width: 48%; + border: none; + border-radius: 10px; + transition: 0.2s; + font-weight: bold; + text-decoration: none; +} + +.buttons *:hover{ + background-color: #077299; +} + +footer a { + color: #CCCCCC; + text-decoration: underline; + margin: 0 10px; +} + +#help{ + display: none; +} + +#help:target{ + display: flex; + align-items: center; + width: 80%; + margin-left: auto; + margin-right: auto; +} + +#help thead tr th { + padding-bottom: 10px; +} + +#help tr.odd { + background-color: var(--background-lighter); +} + +#help tr.even { + background-color: var(--background-darker); +} + +#help td, #help th { + text-align: left; + padding: 5px 20px 5px 5px; +} + +#help td:nth-child(1), #help th:nth-child(1) { + font-weight: bold; + width: 28vw; + max-width: 280px; +} + +#help td:nth-child(2), #help th:nth-child(2), +#help td:nth-child(3), #help th:nth-child(3) { + width: 28vw; + max-width: 220px; +} + diff --git a/pica-whiteboard/docker-compose.yml b/pica-whiteboard/docker-compose.yml index 2e4c6c431ced820c631c83811a5b60199da71860..836d8ea8ac34ac3f5425576a0999e9e464ec0b4e 100644 --- a/pica-whiteboard/docker-compose.yml +++ b/pica-whiteboard/docker-compose.yml @@ -1,16 +1,22 @@ -version: '3' +version: '3.7' services: - app: - image: wb + whiteboard-app: + image: registry.picasoft.net/pica-whiteboard:1.5 + container_name: whiteboard-app build: . + volumes: + - /etc/localtime:/etc/localtime:ro networks: - proxy labels: - traefik.http.routers.etherpad-app.entrypoints: websecure - traefik.http.routers.etherpad-app.rule: Host(`wb.test.picasoft.net`) - traefik.http.services.etherpad-app.loadbalancer.server.port: 8080 + traefik.http.routers.whiteboard-app.entrypoints: websecure + traefik.http.routers.whiteboard-app.rule: Host(`board.picasoft.net`) + traefik.http.services.whiteboard-app.loadbalancer.server.port: 80 traefik.enable: true - restart: always + environment: + STOP_APP: "0 0 * * *" + RESTART_APP: "1 0 * * *" + restart: unless-stopped networks: proxy: diff --git a/pica-whiteboard/entrypoint.sh b/pica-whiteboard/entrypoint.sh index 8e9decd93d3153fca9f21a4bf6d67f72fdf0ea02..618a4d28422752ba64b8b12a30e62480fab82072 100644 --- a/pica-whiteboard/entrypoint.sh +++ b/pica-whiteboard/entrypoint.sh @@ -1,5 +1,10 @@ #! /bin/sh -cd /opt/app/whiteboard-1.5 +cd /opt/whiteboard +cat << EOF > crontab +$STOP_APP pkill node +$RESTART_APP cd /opt/whiteboard && node server.js --mode=production +EOF node server.js --mode=production & -supercronic /opt/app/whiteboard-1.5/crontab +nginx +supercronic crontab diff --git a/pica-whiteboard/index.html b/pica-whiteboard/index.html new file mode 100644 index 0000000000000000000000000000000000000000..f72858486cf0ad42abbd78f6a20432362fb278d4 --- /dev/null +++ b/pica-whiteboard/index.html @@ -0,0 +1,293 @@ +<!DOCTYPE html> +<html> + <head> + <title>Whiteboard Picasoft</title> + <meta charset="utf-8" /> + <link rel="stylesheet" type="text/css" href="default.css" /> + </head> + + <body> + <header> + <h1>Whiteboard de Picasoft</h1> + </header> + + <article class="flex-center-column" > + <img + src="picasoft-logo-whiteboard.png" + alt="Logo de Picasoft" + class="logo margin-small" + /> + + <p class="warning main-center margin-medium"> + Attention, le contenu des tableaux est réinitialisé chaque nuit (à minuit) ! <br/> + Pensez à exporter votre tableau une fois votre séance terminée. + </p> + + <h2 class="margin-small" >Créer un tableau</h2> + <form + class="flex-center-column main-center margin-small" + action="https://board.picasoft.net/app/" method="GET" + > + <label class="margin-small" for="name">Nom du tableau</label> + <input class="margin-small" type="text" id="id" name="whiteboardid" /> + + <label class="margin-small" for="username">Nom d'utilisateur <i>(optionnel)</i></label> + <input class="margin-small" type="text" id="username" name="username" /> + + <div class="buttons flex-row-spacearound margin-medium"> + <input type="submit" value="Lancer le board"/> + <a href="https://board.picasoft.net/app/?randomid=true">Au hasard !</a> + </div> + </form> + + <footer class="main-center flex-row-spacearound margin-medium"> + <a href="#help">Montrer l'aide</a> + <a class="child" href="https://picasoft.net/co/cgu.html">CGU</a> + </footer> + + </article> + + <div id="help" class="margin-big flex-center-column"> + <h2>Quelques raccourcis usuels</h2> + <table class="margin-medium"> + <thead> + <tr class="header"> + <th>Result</th> + <th>Windows and Linux</th> + <th>macOS</th> + </tr> + </thead> + <tbody> + <tr class="odd"> + <td>Clear the whiteboard</td> + <td>Ctrl + Shift + Z</td> + <td>Cmd + Shift + Z</td> + </tr> + <tr class="even"> + <td>Undo your last step</td> + <td>Ctrl + Z</td> + <td>Cmd + Z</td> + </tr> + <tr class="odd"> + <td>Redo your last undo</td> + <td>Ctrl + Y</td> + <td>Cmd + Y</td> + </tr> + <tr class="even"> + <td>Increase thickness</td> + <td>Ctrl + Up Arrow</td> + <td>Cmd + Up Arrow</td> + </tr> + <tr class="odd"> + <td>Decrease thickness</td> + <td>Ctrl + Down Arrow</td> + <td>Cmd + Down Arrow</td> + </tr> + <tr class="even"> + <td>Set a color</td> + <td>Ctrl + Shift + 1,2,3,4,5</td> + <td>Cmd + Shift + 1,2,3,4,5</td> + </tr> + <tr class="odd"> + <td>Toggle between main colors</td> + <td>Ctrl + Shift + R</td> + <td>Cmd + Shift + R</td> + </tr> + </tbody> + </table> + + <h2>Tous les raccourcis</h2> + <table class="margin-medium"> + <thead> + <tr class="header"> + <th>Result</th> + <th>Windows and Linux</th> + <th>macOS</th> + </tr> + </thead> + <tbody> + <tr class="odd"> + <td>Clear the whiteboard</td> + <td>Ctrl + Shift + Z</td> + <td>Cmd + Shift + Z</td> + </tr> + <tr class="even"> + <td>Undo your last step</td> + <td>Ctrl + Z</td> + <td>Cmd + Z</td> + </tr> + <tr class="odd"> + <td>Redo your last undo</td> + <td>Ctrl + Y</td> + <td>Cmd + Y</td> + </tr> + <tr class="even"> + <td>Select an area</td> + <td>Ctrl + X</td> + <td>Cmd + X</td> + </tr> + <tr class="odd"> + <td>Take the mouse</td> + <td>Ctrl + M</td> + <td>Cmd + M</td> + </tr> + <tr class="even"> + <td>Take the pen</td> + <td>Ctrl + P</td> + <td>Cmd + P</td> + </tr> + <tr class="odd"> + <td>Draw a line</td> + <td>Ctrl + L</td> + <td>Cmd + L</td> + </tr> + <tr class="even"> + <td>Draw a rectangle</td> + <td>Ctrl + R</td> + <td>Cmd + R</td> + </tr> + <tr class="odd"> + <td>Draw a circle</td> + <td>Ctrl + C</td> + <td>Cmd + C</td> + </tr> + <tr class="even"> + <td>Toggle between line, rect, circ</td> + <td>Ctrl + Shift + F</td> + <td>Cmd + Shift + F</td> + </tr> + <tr class="odd"> + <td>Toggle between pen and eraser</td> + <td>Ctrl + Shift + X</td> + <td>Cmd + Shift + X</td> + </tr> + <tr class="even"> + <td>Toggle between main clolors</td> + <td>Ctrl + Shift + R</td> + <td>Cmd + Shift + R</td> + </tr> + <tr class="odd"> + <td>Write text</td> + <td>Ctrl + A</td> + <td>Cmd + A</td> + </tr> + <tr class="even"> + <td>Take the eraser</td> + <td>Ctrl + E</td> + <td>Cmd + E</td> + </tr> + <tr class="odd"> + <td>Increase thickness</td> + <td>Ctrl + Up Arrow</td> + <td>Cmd + Up Arrow</td> + </tr> + <tr class="even"> + <td>Decrease thickness</td> + <td>Ctrl + Down Arrow</td> + <td>Cmd + Down Arrow</td> + </tr> + <tr class="odd"> + <td>Colorpicker</td> + <td>Ctrl + Shift + C</td> + <td>Cmd + Shift + C</td> + </tr> + <tr class="even"> + <td>Set black color</td> + <td>Ctrl + Shift + 1</td> + <td>Cmd + Shift + 1</td> + </tr> + <tr class="odd"> + <td>Set blue color</td> + <td>Ctrl + Shift + 2</td> + <td>Cmd + Shift + 2</td> + </tr> + <tr class="even"> + <td>Set green color</td> + <td>Ctrl + Shift + 3</td> + <td>Cmd + Shift + 3</td> + </tr> + <tr class="odd"> + <td>Set yellow color</td> + <td>Ctrl + Shift + 4</td> + <td>Cmd + Shift + 4</td> + </tr> + <tr class="even"> + <td>Set red color</td> + <td>Ctrl + Shift + 5</td> + <td>Cmd + Shift + 5</td> + </tr> + <tr class="odd"> + <td>Save whiteboard as image</td> + <td>Ctrl + S</td> + <td>Cmd + S</td> + </tr> + <tr class="even"> + <td>Save whiteboard as JSON</td> + <td>Ctrl + Shift + K</td> + <td>Cmd + Shift + K</td> + </tr> + <tr class="odd"> + <td>Save whiteboard to WebDav</td> + <td>Ctrl + Shift + I (i)</td> + <td>Cmd + Shift + I (i)</td> + </tr> + <tr class="even"> + <td>Load saved JSON to whiteboard</td> + <td>Ctrl + Shift + J</td> + <td>Cmd + Shift + J</td> + </tr> + <tr class="odd"> + <td>Share whiteboard</td> + <td>Ctrl + Shift + S</td> + <td>Cmd + Shift + S</td> + </tr> + <tr class="even"> + <td>Hide or show toolbar</td> + <td>Tab</td> + <td>Tab</td> + </tr> + <tr class="odd"> + <td>Move selected object up</td> + <td>Up Arrow</td> + <td>Up Arrow</td> + </tr> + <tr class="even"> + <td>Move selected object down</td> + <td>Down Arrow</td> + <td>Down Arrow</td> + </tr> + <tr class="odd"> + <td>Move selected object left</td> + <td>Left Arrow</td> + <td>Left Arrow</td> + </tr> + <tr class="even"> + <td>Move selected object right</td> + <td>Right Arrow</td> + <td>Right Arrow</td> + </tr> + <tr class="odd"> + <td>Drop object</td> + <td>Ctrl + Enter</td> + <td>Cmd + Enter</td> + </tr> + <tr class="even"> + <td>Add Image to backgroud</td> + <td>Shift + Enter</td> + <td>Shift + Enter</td> + </tr> + <tr class="odd"> + <td>Cancel all actions</td> + <td>Escape</td> + <td>Escape</td> + </tr> + <tr class="even"> + <td>Delete selected object</td> + <td>Delete</td> + <td>Delete</td> + </tr> + </tbody> + </table> + </div> + </body> +</html> diff --git a/pica-whiteboard/picasoft-logo-whiteboard.png b/pica-whiteboard/picasoft-logo-whiteboard.png new file mode 100644 index 0000000000000000000000000000000000000000..dbb8f3b49cd49c8670bbfba8e3f09a19eea3e0bd Binary files /dev/null and b/pica-whiteboard/picasoft-logo-whiteboard.png differ diff --git a/pica-whiteboard/picasoft.svg b/pica-whiteboard/picasoft.svg new file mode 100644 index 0000000000000000000000000000000000000000..dea6e3fbb4d73d6c4a86cf71219eb9f5a1d573ed --- /dev/null +++ b/pica-whiteboard/picasoft.svg @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + enable-background="new" + id="svg5580" + version="1.1" + viewBox="0 0 120 120" + height="120mm" + width="120mm" + sodipodi:docname="logo_picasoft_white.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="704" + id="namedview19" + showgrid="false" + inkscape:zoom="0.52034722" + inkscape:cx="216.20179" + inkscape:cy="226.77165" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg5580" /> + <defs + id="defs5574" /> + <metadata + id="metadata5577"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="picasoft_logo_fond_noir" + transform="translate(-32.506122,-7.0588434)"> + <g + id="layer10" + style="display:inline"> + <path + style="display:inline;fill:#ffffff;fill-opacity:0.58823529;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" + d="m 69.015211,83.111666 c 0.03133,-0.615271 3.537744,-0.978125 8.804872,-1.016568 1.911624,0.04462 4.216154,0.175588 6.580278,0.58552 0.815679,0.138499 1.711581,0.329921 2.634368,0.653292 0.364768,0.07244 0.853411,0.276064 1.388583,0.683257 0.232165,0.176645 0.471626,0.390524 0.712126,0.646576 0.529775,0.698664 0.861501,1.382016 1.094882,1.959861 0.369109,0.862869 0.659774,1.717102 0.905951,2.521922 0.662259,2.159645 1.116236,4.263416 1.436066,6.032917 0.728654,4.685654 0.901463,7.789917 0.341855,7.929397 0,0 -10e-7,0 -10e-7,0 -0.0061,0.001 -0.006,0.001 -0.006,0.001 4.2e-5,-1e-5 8.1e-5,0 -0.006,0.001 0,0 -10e-7,0 -10e-7,0 -0.568667,0.0971 -1.738926,-2.79168 -3.065283,-7.283818 -0.52027,-1.610626 -1.178868,-3.717053 -1.871318,-5.622891 -0.269804,-0.741459 -0.553322,-1.49116 -0.875352,-2.192851 -0.246532,-0.508517 -0.440857,-0.944736 -0.667369,-1.203143 0.04555,0.0095 0.05379,0.01542 0.02972,0.01193 -0.05637,-0.0082 -0.278758,-0.06597 -0.590325,-0.237993 -0.633543,-0.238465 -1.358871,-0.403779 -2.103773,-0.565589 -2.063966,-0.441153 -4.327425,-0.743027 -6.132637,-1.00101 -5.194671,-0.570881 -8.641925,-1.288334 -8.61061,-1.903342 z" + id="path4670" + inkscape:connector-curvature="0" /> + <path + id="path4996-8" + d="m 111.29758,46.441617 c -0.003,-0.0051 -0.005,-0.01049 -0.006,-0.01604 -0.002,-0.0054 -0.003,-0.01105 -0.004,-0.01685 -0.002,-0.01159 -0.002,-0.02391 -6.6e-4,-0.03696 0,0 0,0 0,0 v 0 c 0.003,-0.02606 0.0115,-0.05496 0.0264,-0.08667 0,0 0,0 0,0 v 0 c 0.0297,-0.06321 0.0835,-0.137342 0.16044,-0.221731 v 0 c 0.1528,-0.167688 0.39613,-0.375001 0.72278,-0.616284 v 0 c 0.6427,-0.474722 1.60209,-1.076682 2.82414,-1.758641 v 0 c 2.30128,-1.284404 5.5584,-2.869756 9.31465,-4.320967 0.51716,-0.199831 1.04477,-0.397402 1.58136,-0.590905 1.31148,-0.472938 2.5889,-0.889908 3.83881,-1.250767 1.86983,-0.540615 3.57749,-0.927229 5.20554,-1.160175 1.73638,-0.253501 3.16286,-0.293567 4.4351,-0.114955 0.69321,0.09602 1.26413,0.262665 1.7267,0.4767 0.92602,0.422082 1.15989,0.952714 1.06145,1.078233 -0.10606,0.135219 -0.57791,-0.01181 -1.33989,-0.06719 -0.43327,-0.02916 -0.87818,-0.02133 -1.50109,0.03067 -1.17756,0.09962 -2.29552,0.326484 -3.95831,0.745959 -1.52554,0.390736 -3.05245,0.859256 -4.86894,1.462699 -1.20007,0.399264 -2.41545,0.823939 -3.70173,1.287856 -0.52305,0.188646 -1.04091,0.37767 -1.55043,0.564904 -3.71058,1.363744 -7.01903,2.646494 -9.49069,3.520953 v 0 c -1.30313,0.461084 -2.37709,0.811842 -3.14243,1.008043 v 0 c -0.39026,0.100047 -0.70292,0.160618 -0.92757,0.176436 v 0 c -0.11324,0.008 -0.20444,0.0046 -0.27228,-0.01078 v 0 c 0,0 0,0 0,0 -0.034,-0.0077 -0.0622,-0.01844 -0.0844,-0.03227 v 0 c 0,0 0,0 0,0 -0.0111,-0.0069 -0.0207,-0.01463 -0.0288,-0.02311 -0.004,-0.0042 -0.008,-0.0087 -0.011,-0.01334 -0.003,-0.0047 -0.006,-0.0097 -0.009,-0.01483 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path4998-5" + d="m 120.74638,56.093617 c -0.20562,-0.29451 0.82385,-1.410843 2.6583,-2.982487 0,0 0,0 0,0 1.71493,-1.487187 4.10376,-3.376116 6.81324,-5.439813 0.27419,-0.208838 0.55124,-0.419139 0.8311,-0.631017 1.01341,-0.767239 2.06974,-1.559598 2.99785,-2.253291 1.28003,-0.956988 2.45917,-1.833304 3.49104,-2.608395 1.08902,-0.820549 1.99438,-1.505167 2.68751,-2.053627 0.37218,-0.295803 0.67246,-0.534425 0.91018,-0.730021 0,0 0,0 0,0 0.34841,-0.305464 0.6378,-0.498197 0.74358,-0.471749 0.16038,0.04009 0.23366,0.400011 0.001,0.985325 0,-10e-7 0,0 0,0 -0.13137,0.344583 -0.33675,0.721379 -0.62985,1.155014 -0.55748,0.827526 -1.30167,1.690481 -2.31873,2.712267 -0.95358,0.959399 -2.04556,1.949765 -3.30573,3.005175 -0.93158,0.780345 -1.92556,1.570551 -2.97993,2.368793 -0.28322,0.21442 -0.56517,0.425166 -0.84525,0.632038 -2.76314,2.040916 -5.36125,3.71937 -7.33425,4.840739 0,0 0,10e-7 0,10e-7 -2.11165,1.183524 -3.51455,1.765585 -3.7202,1.471048 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5000-8" + d="m 119.62878,56.703217 c 0.2693,-0.0936 1.08944,1.462402 2.26985,4.201523 0,0 0,1e-6 0,1e-6 1.0105,2.747842 2.07054,6.705728 2.45773,11.521844 0.23428,2.925856 0.20217,6.113789 -0.24553,9.434785 -0.30279,2.246101 -0.77292,4.383286 -1.38107,6.395867 0,0 0,3e-6 0,3e-6 -1.65539,5.458879 -4.25599,9.649814 -6.41365,12.38145 -2.16058,2.73535 -3.81915,3.98797 -4.02102,3.80896 -0.25602,-0.22704 0.96356,-1.85665 2.67623,-4.7364 1.71746,-2.887816 3.88834,-7.007875 5.29646,-12.164493 0,0 0,-2e-6 0,-2e-6 0.52281,-1.906454 0.93688,-3.919651 1.22155,-6.038227 0.42062,-3.130279 0.51225,-6.143793 0.40405,-8.934388 -0.17586,-4.584332 -0.86745,-8.410048 -1.45301,-11.206352 0,0 0,-10e-7 0,-10e-7 -0.75994,-2.843333 -1.08076,-4.571019 -0.81159,-4.66457 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5002-2" + d="m 112.26962,105.48504 c 0.004,4e-5 0.008,9.2e-4 0.0125,0.003 0.004,0.002 0.008,0.004 0.0121,0.008 0,0 0,0 0,0 0.008,0.007 0.0159,0.017 0.0236,0.0304 0,0 0,0 0,0 v 0 c 0.0154,0.0268 0.0301,0.0664 0.0437,0.11847 v 0 0 c 0.027,0.10329 0.0494,0.25367 0.0637,0.44964 v 0 c 0.0279,0.38181 0.0249,0.92764 -0.0438,1.61097 v 0 c -0.12704,1.2694 -0.48617,3.06434 -1.3871,4.947 v 0 c -0.4305,0.89913 -0.98846,1.81466 -1.69949,2.67543 -0.16979,0.20541 -0.34802,0.40697 -0.53463,0.60385 -0.64013,0.67534 -1.33714,1.2516 -2.06286,1.72741 -1.2231,0.80036 -2.48807,1.29328 -3.62103,1.58211 -2.85185,0.72584 -4.707298,0.28587 -4.708162,0.1905 -0.0017,-0.19112 1.874822,-0.2148 4.447062,-1.07983 1.03371,-0.34722 2.17675,-0.85707 3.2651,-1.61061 0.64745,-0.44732 1.27283,-0.97819 1.8545,-1.5919 0.16962,-0.17897 0.33237,-0.36165 0.4882,-0.54736 0.65345,-0.77817 1.18586,-1.6096 1.61788,-2.42831 v 0 c 0.90349,-1.71146 1.38154,-3.39002 1.67171,-4.58176 v 0 c 0.15603,-0.64221 0.26095,-1.16208 0.34393,-1.52489 v 0 c 0.0424,-0.18531 0.0797,-0.33166 0.11349,-0.42916 v 0 0 c 0.0172,-0.0497 0.034,-0.0879 0.0503,-0.1134 v 0 c 0,0 0,0 0,0 0.008,-0.0129 0.0164,-0.0227 0.0245,-0.0292 0,0 0,0 0,0 0.004,-0.003 0.008,-0.006 0.0122,-0.007 0.004,-0.002 0.008,-0.003 0.0125,-0.002 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5004-6" + d="m 98.041468,119.28759 c 0.03621,0.1032 -0.997952,0.57339 -2.796793,1.29237 -1.705181,0.53162 -4.231231,1.04717 -7.17191,0.82596 -1.428834,-0.10925 -2.942727,-0.39851 -4.460436,-0.93275 -0.673159,-0.23724 -1.341773,-0.52119 -2.000407,-0.8523 -0.933235,-0.46916 -1.80161,-1.01046 -2.598829,-1.60044 -1.823282,-1.35043 -3.260035,-2.9307 -4.356259,-4.41271 -2.81747,-3.80896 -3.555316,-6.84934 -3.513966,-6.86773 0.164266,-0.0731 1.351233,2.80868 4.193206,6.34421 1.11529,1.3874 2.529835,2.86919 4.269934,4.1258 0.760726,0.54983 1.584086,1.05683 2.464189,1.49949 0.62123,0.31244 1.250024,0.5824 1.881919,0.81027 1.424337,0.51427 2.851062,0.81185 4.204189,0.95116 2.769573,0.28891 5.218421,-0.0806 6.915692,-0.45226 1.832942,-0.5555 2.933273,-0.83422 2.969471,-0.73107 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5006-0" + d="m 72.209668,112.22639 c -0.278415,0.12733 -1.466781,-2.26347 -4.405235,-5.39066 -1.313886,-1.39982 -2.812083,-2.75132 -4.776469,-4.34174 -1.544513,-1.24884 -3.285752,-2.556908 -5.107406,-4.045303 -1.62193,-1.32305 -3.346798,-2.842261 -4.920507,-4.597899 -1.506128,-1.682069 -2.875325,-3.614548 -3.956158,-5.780246 -0.03571,-0.07156 -0.07105,-0.143254 -0.106015,-0.215087 -1.28919,-2.662331 -2.044586,-5.443925 -2.433455,-8.112893 -0.570038,-3.916161 -0.430251,-7.68382 -0.08862,-10.860259 0.463903,-4.333218 1.343938,-8.061907 2.022045,-10.426281 0.702104,-2.448047 1.276843,-3.78222 1.486085,-3.731458 0.439035,0.106512 -0.895277,5.745955 -1.335826,14.330615 -0.156409,3.07872 -0.160883,6.683336 0.448002,10.290619 0.414007,2.454199 1.124088,4.98181 2.281374,7.353105 0.03108,0.06406 0.06251,0.12803 0.09427,0.191904 0.960656,1.931794 2.186553,3.687688 3.534208,5.246506 1.409252,1.631888 3.015575,3.115287 4.543596,4.456199 1.723354,1.509763 3.416535,2.907808 4.927768,4.281768 1.91132,1.7354 3.406485,3.31698 4.627397,4.91091 2.806407,3.66699 3.354064,6.3537 3.164947,6.4402 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5008-6" + d="m 49.857374,55.003431 c -0.0058,0.0017 -0.01195,0.0025 -0.01834,0.0023 -0.0065,-9.26e-4 -0.01343,-0.003 -0.0207,-0.0064 0,0 0,0 0,0 -0.01449,-0.0068 -0.03043,-0.01868 -0.04778,-0.03554 0,0 -10e-7,0 -10e-7,0 v 0 c -0.03453,-0.03357 -0.0746,-0.08688 -0.120023,-0.159539 v 0 c -0.08986,-0.143756 -0.200148,-0.362447 -0.32919,-0.653558 v 0 C 49.069684,53.582977 48.749375,52.746358 48.37565,51.6594 v 0 c -0.689762,-2.006162 -1.58372,-4.928385 -2.490712,-8.48943 v 0 c -0.779594,-3.059811 -1.62608,-6.800163 -2.256745,-10.828263 v 0 C 43.358706,30.620729 43.122006,28.797031 42.969582,26.91657 v 0 c -0.130015,-1.595675 -0.202824,-3.274774 -0.1389,-4.990581 v 0 c 0.04747,-1.36672 0.189495,-2.814827 0.564792,-4.267956 v 0 c 0.15256,-0.590187 0.357194,-1.194205 0.63763,-1.791667 v 0 c 0.24047,-0.516743 0.55704,-1.032879 0.968434,-1.514478 0.374724,-0.437628 0.83813,-0.823388 1.382133,-1.121894 0,0 6e-6,-2e-6 6e-6,-2e-6 0.554245,-0.295592 1.14908,-0.474713 1.749905,-0.539145 0.09736,-0.01 0.194199,-0.0175 0.290467,-0.02271 0.584846,-0.03166 1.144587,0.02259 1.664203,0.134296 0.760984,0.160589 1.465207,0.413292 2.110287,0.707853 1.860718,0.84936 3.473047,2.011201 4.898674,3.172922 2.273088,1.839802 4.302522,3.859106 6.103291,5.777768 2.870783,3.056007 5.414847,6.151393 7.48788,8.800603 0,0 2e-6,3e-6 2e-6,3e-6 5.73866,7.332555 8.798238,12.368396 8.531684,12.566832 -0.374743,0.278975 -4.012682,-4.329316 -10.076072,-11.291787 -10e-7,-1e-6 -10e-7,-1e-6 -3e-6,-2e-6 -2.175285,-2.497527 -4.832036,-5.489206 -7.697589,-8.384882 -1.812003,-1.829493 -3.805936,-3.742843 -5.966455,-5.44295 -1.376374,-1.075459 -2.816786,-2.111935 -4.361906,-2.791397 -0.527432,-0.231754 -1.04982,-0.423278 -1.562371,-0.52452 -0.346596,-0.06639 -0.679759,-0.104318 -0.983303,-0.08604 -0.04998,0.003 -0.09912,0.0075 -0.147352,0.01371 -0.28685,0.03395 -0.560373,0.111724 -0.786413,0.236859 0,0 -3e-6,0 -3e-6,0 -0.229104,0.118353 -0.446861,0.305078 -0.643487,0.525474 -0.223409,0.249505 -0.412784,0.566362 -0.584828,0.915718 v 0 c -0.198318,0.40771 -0.351393,0.859279 -0.481584,1.332805 v 0 c -0.324025,1.177771 -0.454534,2.443596 -0.52477,3.709637 v 0 c -0.08336,1.578412 -0.04166,3.164459 0.04788,4.701571 v 0 c 0.106044,1.807414 0.28874,3.584178 0.497958,5.273199 v 0 c 0.487144,3.931793 1.161641,7.703827 1.739492,10.753495 0.681486,3.595224 1.298606,6.524888 1.705908,8.616725 v 0 c 0.21787,1.11891 0.377857,2.003075 0.461358,2.612451 v 0 c 0.043,0.313817 0.06617,0.557534 0.0674,0.726078 v 0 c 6.62e-4,0.08537 -0.0044,0.151729 -0.01523,0.198481 v 0 c 0,0 0,0 0,0 -0.0054,0.02352 -0.0124,0.04211 -0.02085,0.05568 0,0 0,1e-6 0,1e-6 -0.0042,0.0068 -0.0089,0.01236 -0.01387,0.01663 -0.0052,0.0037 -0.01078,0.0063 -0.01661,0.0081 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + id="path5010-6" + d="m 76.240832,36.655265 c -0.01583,-0.544631 4.813562,-1.152415 11.749779,-1.555686 2.396645,0.03992 5.008121,0.218258 7.762356,0.589753 1.612575,0.217506 3.163809,0.486352 4.645483,0.795383 0,0 1e-5,0 1e-5,0 4.2622,0.892146 7.74943,2.08406 10.23746,3.169327 2.45478,1.070766 3.79339,1.969286 3.6812,2.245691 -0.12132,0.298879 -1.67089,-0.06594 -4.20916,-0.687732 -2.65875,-0.651306 -5.96028,-1.462443 -10.194996,-2.203378 0,0 -2e-6,-2e-6 -2e-6,-2e-6 -1.435862,-0.252145 -2.925834,-0.48658 -4.477884,-0.697666 -2.655421,-0.36115 -5.143774,-0.606564 -7.46465,-0.782278 -6.867943,-0.0018 -11.71378,-0.329118 -11.729596,-0.873412 z" + style="display:inline;fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + inkscape:connector-curvature="0" /> + <path + style="fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 94.10447,112.96722 c 0.0036,-0.006 0.0076,-0.0122 0.01214,-0.0178 0.0044,-0.005 0.0092,-0.0107 0.01442,-0.0156 0.01044,-0.01 0.02262,-0.0187 0.03643,-0.0266 0,0 0,0 0,0 v 0 c 0.0274,-0.0156 0.06157,-0.0275 0.101887,-0.0355 v 0 c 0.07988,-0.016 0.185667,-0.0181 0.313832,-0.008 v 0 c 0.250163,0.0192 0.598334,0.0839 1.0149,0.17159 v 0 c 0.812484,0.17065 1.899728,0.42997 3.165949,0.59738 0.676372,0.088 1.401702,0.15022 2.148492,0.15484 0.6466,0.004 1.25525,-0.0355 1.83405,-0.11539 0,0 0,0 0,0 1.32577,-0.17686 2.42335,-0.56992 3.24047,-0.87699 0.80894,-0.30399 1.33015,-0.51259 1.47783,-0.33569 0.13417,0.16073 -0.12412,0.69741 -0.86003,1.34289 -0.73192,0.64198 -1.92947,1.36559 -3.52366,1.71756 0,0 0,0 0,0 -0.68632,0.14919 -1.41649,0.22804 -2.17802,0.2253 -0.88284,-0.003 -1.718001,-0.11561 -2.475391,-0.29264 -1.411553,-0.32747 -2.536707,-0.85789 -3.281224,-1.33858 v 0 c -0.387048,-0.24965 -0.672212,-0.48615 -0.849553,-0.68522 v 0 c -0.09,-0.10104 -0.151774,-0.19151 -0.1844,-0.26932 v 0 c -0.01642,-0.0392 -0.02549,-0.0747 -0.02695,-0.1068 v 0 c 0,0 0,0 0,0 -6.62e-4,-0.016 5.29e-4,-0.0311 0.0035,-0.0452 0.0015,-0.007 0.0036,-0.0139 0.006,-0.0204 0.0026,-0.007 0.0056,-0.0133 0.0092,-0.0195 z" + id="path5045-4" + inkscape:connector-curvature="0" /> + <path + style="fill:#ffffff;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 97.220701,116.52375 c -0.08463,-0.3431 0.78561,-0.85317 1.942508,-1.13854 1.156901,-0.28537 2.164521,-0.23852 2.249151,0.10458 0.0846,0.3431 -0.78561,0.85316 -1.94251,1.13854 -1.156897,0.28537 -2.164517,0.23852 -2.249149,-0.10458 z" + id="path5049-6" + inkscape:connector-curvature="0" /> + <path + style="display:inline;fill:#ffffff;fill-opacity:0.58823529;stroke:none;stroke-width:0.42333335;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 98.967983,47.853918 a 2.4999998,2.4999998 0 0 0 -2.499591,2.494941 l -0.004,-0.01188 -5.635827,2.082043 a 3.4999999,3.4999999 0 0 0 -2.868577,-1.501714 3.4999999,3.4999999 0 0 0 -3.500049,3.500046 3.4999999,3.4999999 0 0 0 3.500049,3.500043 3.4999999,3.4999999 0 0 0 3.499517,-3.500043 3.4999999,3.4999999 0 0 0 -0.0284,-0.408247 L 96.73104,52.05109 86.791086,65.345884 a 2.9999998,2.9999998 0 0 0 -1.137399,-0.225309 2.9999998,2.9999998 0 0 0 -2.999827,2.999817 2.9999998,2.9999998 0 0 0 2.999827,3.000332 2.9999998,2.9999998 0 0 0 2.999809,-3.000332 2.9999998,2.9999998 0 0 0 -0.574119,-1.759067 l 0.0481,0.03617 10.185932,-13.623975 -0.01961,-0.01447 a 2.4999998,2.4999998 0 0 0 0.67437,0.09508 2.4999998,2.4999998 0 0 0 0.625808,-0.08113 l -0.0269,0.0181 8.743653,12.907737 a 2.9999998,2.9999998 0 0 0 -0.44598,0.702803 l -3.1812,-0.455788 -10e-4,0.0083 a 2.4999998,2.4999998 0 0 0 -2.43758,-1.959057 2.4999998,2.4999998 0 0 0 -2.500102,2.500106 2.4999998,2.4999998 0 0 0 2.500102,2.500109 2.4999998,2.4999998 0 0 0 2.22312,-1.362707 l 3.15795,0.452683 a 2.9999998,2.9999998 0 0 0 0.0501,0.256318 l -9.010815,4.952151 0.0284,0.05116 a 3.4999999,3.4999999 0 0 0 -2.62723,-1.193724 3.4999999,3.4999999 0 0 0 -3.500037,3.500045 3.4999999,3.4999999 0 0 0 3.500037,3.500046 3.4999999,3.4999999 0 0 0 3.50004,-3.500046 3.4999999,3.4999999 0 0 0 -0.138488,-0.968936 l 0.008,0.01394 9.010813,-4.952151 a 2.9999998,2.9999998 0 0 0 2.14457,0.902272 2.9999998,2.9999998 0 0 0 2.99983,-2.999817 2.9999998,2.9999998 0 0 0 -2.31717,-2.918169 l -0.31419,-7.600089 a 3.4999999,3.4999999 0 0 0 2.56469,-3.372403 3.4999999,3.4999999 0 0 0 -3.50004,-3.500046 3.4999999,3.4999999 0 0 0 -3.50004,3.500046 3.4999999,3.4999999 0 0 0 2.836,3.434932 l 0.31006,7.484298 -8.69452,-12.835906 a 2.4999998,2.4999998 0 0 0 0.49248,-1.48518 2.4999998,2.4999998 0 0 0 -2.500106,-2.500106 z" + id="circle4819-5" + inkscape:connector-curvature="0" /> + </g> + </g> +</svg>