From fcd506177a0d9903f52734c3546484961079b9e1 Mon Sep 17 00:00:00 2001 From: Michael RICOIS Date: Mon, 30 Jan 2017 11:35:09 +0100 Subject: [PATCH] =?UTF-8?q?Envoi=20des=20=C3=A9l=C3=A9ments=20docker=20des?= =?UTF-8?q?=20serveurs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + compose/dev/docker-compose.yml | 80 ++++++++ compose/sd-25137/docker-compose.yml | 12 ++ compose/sd-48233/docker-compose.yml | 12 ++ compose/vmmanager5/docker-compose.yml | 13 ++ templates/mariadb/10.0/Dockerfile | 34 ++++ templates/mariadb/10.0/init_user.sh | 32 +++ templates/mariadb/10.0/my.cnf | 6 + templates/mariadb/10.0/run.sh | 17 ++ templates/mariadb/10.1/Dockerfile | 32 +++ templates/mariadb/10.1/init_user.sh | 32 +++ templates/mariadb/10.1/my.cnf | 6 + templates/mariadb/10.1/run.sh | 15 ++ templates/mariadb/5.5/Dockerfile | 32 +++ templates/mariadb/5.5/init_user.sh | 32 +++ templates/mariadb/5.5/my.cnf | 6 + templates/mariadb/5.5/run.sh | 15 ++ templates/mariadb/README.md | 67 +++++++ templates/mariadb/config/default.my.cnf.txt | 62 ++++++ templates/mariadb/config/master.my.cnf.txt | 12 ++ templates/mariadb/config/slave.my.cnf.txt | 76 +++++++ templates/mysql/5.5/Dockerfile | 33 ++++ templates/mysql/5.5/docker-compose.yml | 4 + templates/mysql/5.5/my.cnf | 6 + templates/mysql/5.5/run.sh | 186 +++++++++++++++++ templates/mysql/5.5/sql-slaveusers.sql | 51 +++++ templates/mysql/5.5/sql_import.sh | 28 +++ templates/mysql/5.6/Dockerfile | 32 +++ templates/mysql/5.6/docker-compose.yml | 4 + templates/mysql/5.6/import_sql.sh | 28 +++ templates/mysql/5.6/my.cnf | 6 + templates/mysql/5.6/mysqld_charset.cnf | 7 + templates/mysql/5.6/run.sh | 187 ++++++++++++++++++ templates/mysql/README.md | 164 +++++++++++++++ templates/mysql/test.sh | 51 +++++ templates/sphinxsearch/Dockerfile | 41 ++++ templates/sphinxsearch/README | 50 +++++ templates/sphinxsearch/cron-sphinxsearch | 13 ++ templates/sphinxsearch/logrotate-sphinxsearch | 10 + templates/sphinxsearch/run.sh | 69 +++++++ templates/sphinxsearch/sdsphinx.tar.gz | Bin 0 -> 18190 bytes templates/sphinxsearch/supervisord.conf | 14 ++ 42 files changed, 1578 insertions(+) create mode 100644 .gitignore create mode 100755 compose/dev/docker-compose.yml create mode 100755 compose/sd-25137/docker-compose.yml create mode 100755 compose/sd-48233/docker-compose.yml create mode 100755 compose/vmmanager5/docker-compose.yml create mode 100755 templates/mariadb/10.0/Dockerfile create mode 100755 templates/mariadb/10.0/init_user.sh create mode 100755 templates/mariadb/10.0/my.cnf create mode 100755 templates/mariadb/10.0/run.sh create mode 100755 templates/mariadb/10.1/Dockerfile create mode 100755 templates/mariadb/10.1/init_user.sh create mode 100755 templates/mariadb/10.1/my.cnf create mode 100755 templates/mariadb/10.1/run.sh create mode 100755 templates/mariadb/5.5/Dockerfile create mode 100755 templates/mariadb/5.5/init_user.sh create mode 100755 templates/mariadb/5.5/my.cnf create mode 100755 templates/mariadb/5.5/run.sh create mode 100755 templates/mariadb/README.md create mode 100755 templates/mariadb/config/default.my.cnf.txt create mode 100755 templates/mariadb/config/master.my.cnf.txt create mode 100755 templates/mariadb/config/slave.my.cnf.txt create mode 100755 templates/mysql/5.5/Dockerfile create mode 100755 templates/mysql/5.5/docker-compose.yml create mode 100755 templates/mysql/5.5/my.cnf create mode 100755 templates/mysql/5.5/run.sh create mode 100755 templates/mysql/5.5/sql-slaveusers.sql create mode 100755 templates/mysql/5.5/sql_import.sh create mode 100755 templates/mysql/5.6/Dockerfile create mode 100755 templates/mysql/5.6/docker-compose.yml create mode 100755 templates/mysql/5.6/import_sql.sh create mode 100755 templates/mysql/5.6/my.cnf create mode 100755 templates/mysql/5.6/mysqld_charset.cnf create mode 100755 templates/mysql/5.6/run.sh create mode 100755 templates/mysql/README.md create mode 100755 templates/mysql/test.sh create mode 100755 templates/sphinxsearch/Dockerfile create mode 100755 templates/sphinxsearch/README create mode 100755 templates/sphinxsearch/cron-sphinxsearch create mode 100755 templates/sphinxsearch/logrotate-sphinxsearch create mode 100755 templates/sphinxsearch/run.sh create mode 100755 templates/sphinxsearch/sdsphinx.tar.gz create mode 100755 templates/sphinxsearch/supervisord.conf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8fe4fa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.project diff --git a/compose/dev/docker-compose.yml b/compose/dev/docker-compose.yml new file mode 100755 index 0000000..3d2600d --- /dev/null +++ b/compose/dev/docker-compose.yml @@ -0,0 +1,80 @@ +version: '2' +services: + gogs: + container_name: gogs + image: gogs/gogs:0.9.97 + ports: + - "10022:22" + - "10080:3000" + volumes: + - /media/disk02/gogs/data:/data + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "9" + bigdata: + container_name: bigdata + image: scores/mariadb101:201602 + ports: + - "3306:3306" + mem_limit: 16g + volumes: + - /media/bigdata-vol1:/var/lib/mysql + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "9" + environment: + MARIADB_PASS: scores + sphinx: + container_name: sphinx + image: scores/sphinxsearch:20160302 + ports: + - "9306:9306" + - "9312:9312" + mem_limit: 16g + volumes: + - /media/disk02/sphinxsearch/data:/var/lib/sphinxsearch + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "9" + environment: + MYSQL_HOST: 192.168.78.249 + MYSQL_USER: sphinx + MYSQL_PASS: indexer + SLAVE: 1 + INDEX_ACT: 1 + INDEX_CIBLAGE: 1 + INDEX_DIR: 1 + INDEX_ENT: 1 + INDEX_DIR: 1 + INDEX_HISTO: 1 + app-db: + container_name: app-db + image: scores/mariadb101:201602 + ports: + - "3307:3306" + mem_limit: 1g + volumes: + - /media/disk02/appsdb:/var/lib/mysql + logging: + driver: "json-file" + options: + max-size: "500m" + max-file: "9" + environment: + MARIADB_PASS: scores + app-imapproxy: + container_name: app-imapproxy + image: scores/imapproxy:201601 + ports: + - "1143:143" + environment: + SERVER_HOSTNAME: "imap.online.net" + ENABLE_SELECT_CACHE: "yes" + FORCE_TLS: "no" + \ No newline at end of file diff --git a/compose/sd-25137/docker-compose.yml b/compose/sd-25137/docker-compose.yml new file mode 100755 index 0000000..bf4587c --- /dev/null +++ b/compose/sd-25137/docker-compose.yml @@ -0,0 +1,12 @@ +sphinx: + container_name: sphinx + image: scores/sphinxsearch + ports: + - "9306:9306" + - "9312:9312" + volumes: + - /media/disk02/sphinxsearch/data:/var/lib/sphinxsearch + log_driver: "json-file" + log_opt: + max-size: "500m" + max-file: "9" \ No newline at end of file diff --git a/compose/sd-48233/docker-compose.yml b/compose/sd-48233/docker-compose.yml new file mode 100755 index 0000000..25746fd --- /dev/null +++ b/compose/sd-48233/docker-compose.yml @@ -0,0 +1,12 @@ +bigdata: + container_name: bigdata03 + image: scores/mariadb55 + ports: + - "3306:3306" + mem_limit: 68719476736 + volumes: + - /media/docker-data/bigdata-vol1:/var/lib/mysql + log_driver: "json-file" + log_opt: + max-size: "500m" + max-file: "9" \ No newline at end of file diff --git a/compose/vmmanager5/docker-compose.yml b/compose/vmmanager5/docker-compose.yml new file mode 100755 index 0000000..b25706e --- /dev/null +++ b/compose/vmmanager5/docker-compose.yml @@ -0,0 +1,13 @@ +bigdata: + container_name: bigdata + image: scores/mariadb55:v48 + ports: + - "13306:3306" + - "3306:3306" + mem_limit: 68719476736 + volumes: + - /mnt/part01/bigdata02:/var/lib/mysql + log_driver: "json-file" + log_opt: + max-size: "500m" + max-file: "9" \ No newline at end of file diff --git a/templates/mariadb/10.0/Dockerfile b/templates/mariadb/10.0/Dockerfile new file mode 100755 index 0000000..59d94ae --- /dev/null +++ b/templates/mariadb/10.0/Dockerfile @@ -0,0 +1,34 @@ +FROM ubuntu:14.04 + +ENV TERM xterm +ENV DEBIAN_FRONTEND noninteractive + +# Installation +RUN apt-get -y install software-properties-common && \ + apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db && \ + add-apt-repository 'deb [arch=amd64,i386] http://mirror6.layerjet.com/mariadb/repo/10.0/ubuntu trusty main' && \ + apt-get update && apt-get -y upgrade && apt-get install -y mariadb-server-10.0 pwgen && \ + rm -rf /var/lib/mysql/* && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + sed -i -e 's/log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/#log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/g' /etc/mysql/my.cnf && \ + sed -i -e 's/log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/#log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/g' /etc/mysql/my.cnf && \ + sed -i -r 's/syslog/log_error=\/var\/log\/errorlog.err/' /etc/mysql/conf.d/mysqld_safe_syslog.cnf && \ + ln -s /dev/stderr /var/log/errorlog.err && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +# Add MySQL configuration +ADD *.cnf /etc/mysql/conf.d/ +RUN chmod 644 /etc/mysql/conf.d/*.cnf + +# Add cli to run +ADD init_user.sh /home/init_user.sh +ADD run.sh /home/run.sh +RUN chmod 775 /home/*.sh + +# Add VOLUMEs to allow backup of config and databases +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 +CMD ["/home/run.sh"] + diff --git a/templates/mariadb/10.0/init_user.sh b/templates/mariadb/10.0/init_user.sh new file mode 100755 index 0000000..cabc48d --- /dev/null +++ b/templates/mariadb/10.0/init_user.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +/usr/bin/mysqld_safe > /dev/null 2>&1 & + +RET=1 +while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MariaDB service startup" + sleep 5 + mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? +done + + +PASS=${MARIADB_PASS:-$(pwgen -s 12 1)} +_word=$( [ ${MARIADB_PASS} ] && echo "preset" || echo "random" ) +echo "=> Creating MariaDB admin user with ${_word} password" + +mysql -uroot -e "CREATE USER 'admin'@'%' IDENTIFIED BY '$PASS'" +mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION" + +echo "=> Done!" + +echo "========================================================================" +echo "You can now connect to this MariaDB Server using:" +echo "" +echo " mysql -uadmin -p$PASS -h -P" +echo "" +echo "Please remember to change the above password as soon as possible!" +echo "MariaDB user 'root' has no password but only allows local connections" +echo "========================================================================" + +mysqladmin -uroot shutdown diff --git a/templates/mariadb/10.0/my.cnf b/templates/mariadb/10.0/my.cnf new file mode 100755 index 0000000..90089a6 --- /dev/null +++ b/templates/mariadb/10.0/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +bind-address=0.0.0.0 +skip_name_resolve +skip_external_locking +#server-id +#log-bin diff --git a/templates/mariadb/10.0/run.sh b/templates/mariadb/10.0/run.sh new file mode 100755 index 0000000..118a830 --- /dev/null +++ b/templates/mariadb/10.0/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +VOLUME_HOME="/var/lib/mysql" + +if [[ ! -d $VOLUME_HOME/mysql ]]; then + echo "=> An empty or uninitialized MariaDB volume is detected in $VOLUME_HOME" + echo "=> Installing MariaDB ..." + mysql_install_db > /dev/null 2>&1 + echo "=> Done!" + /home/init_user.sh +else + echo "=> Using an existing volume of MariaDB" +fi + +/home/init_config.sh + +exec mysqld_safe diff --git a/templates/mariadb/10.1/Dockerfile b/templates/mariadb/10.1/Dockerfile new file mode 100755 index 0000000..055f8d8 --- /dev/null +++ b/templates/mariadb/10.1/Dockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:14.04 + +ENV TERM xterm +ENV DEBIAN_FRONTEND noninteractive + +# Installation +RUN apt-get update && apt-get -y install software-properties-common && \ + apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db && \ + add-apt-repository 'deb [arch=amd64,i386] http://ftp.igh.cnrs.fr/pub/mariadb/repo/10.1/ubuntu trusty main' && \ + apt-get update && apt-get -y upgrade && apt-get -y install mariadb-server-10.1 pwgen && \ + rm -rf /var/lib/mysql/* && \ + apt-get clean && rm -rf /var/lib/apt/lists/* && \ + sed -i -e 's/log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/#log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/g' /etc/mysql/my.cnf && \ + sed -i -e 's/log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/#log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/g' /etc/mysql/my.cnf && \ + sed -i -r 's/syslog/log_error=\/var\/log\/errorlog.err/' /etc/mysql/conf.d/mysqld_safe_syslog.cnf && \ + ln -s /dev/stderr /var/log/errorlog.err && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +# Add MySQL configuration +ADD *.cnf /etc/mysql/conf.d/ +RUN chmod 644 /etc/mysql/conf.d/*.cnf + +# Add cli to run +ADD init_user.sh /home/init_user.sh +ADD run.sh /home/run.sh +RUN chmod 775 /home/*.sh + +# Add VOLUMEs to allow backup of config and databases +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 +CMD ["/home/run.sh"] diff --git a/templates/mariadb/10.1/init_user.sh b/templates/mariadb/10.1/init_user.sh new file mode 100755 index 0000000..cabc48d --- /dev/null +++ b/templates/mariadb/10.1/init_user.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +/usr/bin/mysqld_safe > /dev/null 2>&1 & + +RET=1 +while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MariaDB service startup" + sleep 5 + mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? +done + + +PASS=${MARIADB_PASS:-$(pwgen -s 12 1)} +_word=$( [ ${MARIADB_PASS} ] && echo "preset" || echo "random" ) +echo "=> Creating MariaDB admin user with ${_word} password" + +mysql -uroot -e "CREATE USER 'admin'@'%' IDENTIFIED BY '$PASS'" +mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION" + +echo "=> Done!" + +echo "========================================================================" +echo "You can now connect to this MariaDB Server using:" +echo "" +echo " mysql -uadmin -p$PASS -h -P" +echo "" +echo "Please remember to change the above password as soon as possible!" +echo "MariaDB user 'root' has no password but only allows local connections" +echo "========================================================================" + +mysqladmin -uroot shutdown diff --git a/templates/mariadb/10.1/my.cnf b/templates/mariadb/10.1/my.cnf new file mode 100755 index 0000000..90089a6 --- /dev/null +++ b/templates/mariadb/10.1/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +bind-address=0.0.0.0 +skip_name_resolve +skip_external_locking +#server-id +#log-bin diff --git a/templates/mariadb/10.1/run.sh b/templates/mariadb/10.1/run.sh new file mode 100755 index 0000000..b862ecc --- /dev/null +++ b/templates/mariadb/10.1/run.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +VOLUME_HOME="/var/lib/mysql" + +if [[ ! -d $VOLUME_HOME/mysql ]]; then + echo "=> An empty or uninitialized MariaDB volume is detected in $VOLUME_HOME" + echo "=> Installing MariaDB ..." + mysql_install_db > /dev/null 2>&1 + echo "=> Done!" + /home/init_user.sh +else + echo "=> Using an existing volume of MariaDB" +fi + +exec mysqld_safe diff --git a/templates/mariadb/5.5/Dockerfile b/templates/mariadb/5.5/Dockerfile new file mode 100755 index 0000000..9d6167c --- /dev/null +++ b/templates/mariadb/5.5/Dockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:14.04 + +ENV TERM xterm +ENV DEBIAN_FRONTEND noninteractive + +# Installation +RUN apt-get update && apt-get -y install software-properties-common && \ + apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db && \ + add-apt-repository 'deb [arch=amd64,i386] http://ftp.igh.cnrs.fr/pub/mariadb/repo/5.5/ubuntu trusty main' && \ + apt-get update && apt-get -y upgrade && apt-get -y install mariadb-server-5.5 pwgen && \ + rm -rf /var/lib/mysql/* && \ + apt-get clean && rm -rf /var/lib/apt/lists/* && \ + sed -i -e 's/log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/#log_bin[ \t]*= \/var\/log\/mysql\/mariadb-bin/g' /etc/mysql/my.cnf && \ + sed -i -e 's/log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/#log_bin_index[ \t]*= \/var\/log\/mysql\/mariadb-bin.index/g' /etc/mysql/my.cnf && \ + sed -i -r 's/syslog/log_error=\/var\/log\/errorlog.err/' /etc/mysql/conf.d/mysqld_safe_syslog.cnf && \ + ln -s /dev/stderr /var/log/errorlog.err && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +# Add MySQL configuration +ADD *.cnf /etc/mysql/conf.d/ +RUN chmod 644 /etc/mysql/conf.d/*.cnf + +# Add cli to run +ADD init_user.sh /home/init_user.sh +ADD run.sh /home/run.sh +RUN chmod 775 /home/*.sh + +# Add VOLUMEs to allow backup of config and databases +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 +CMD ["/home/run.sh"] diff --git a/templates/mariadb/5.5/init_user.sh b/templates/mariadb/5.5/init_user.sh new file mode 100755 index 0000000..cabc48d --- /dev/null +++ b/templates/mariadb/5.5/init_user.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +/usr/bin/mysqld_safe > /dev/null 2>&1 & + +RET=1 +while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MariaDB service startup" + sleep 5 + mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? +done + + +PASS=${MARIADB_PASS:-$(pwgen -s 12 1)} +_word=$( [ ${MARIADB_PASS} ] && echo "preset" || echo "random" ) +echo "=> Creating MariaDB admin user with ${_word} password" + +mysql -uroot -e "CREATE USER 'admin'@'%' IDENTIFIED BY '$PASS'" +mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION" + +echo "=> Done!" + +echo "========================================================================" +echo "You can now connect to this MariaDB Server using:" +echo "" +echo " mysql -uadmin -p$PASS -h -P" +echo "" +echo "Please remember to change the above password as soon as possible!" +echo "MariaDB user 'root' has no password but only allows local connections" +echo "========================================================================" + +mysqladmin -uroot shutdown diff --git a/templates/mariadb/5.5/my.cnf b/templates/mariadb/5.5/my.cnf new file mode 100755 index 0000000..e311eb5 --- /dev/null +++ b/templates/mariadb/5.5/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +bind-address=0.0.0.0 +skip-name-resolve +skip_external_locking +#server-id +#log-bin diff --git a/templates/mariadb/5.5/run.sh b/templates/mariadb/5.5/run.sh new file mode 100755 index 0000000..b862ecc --- /dev/null +++ b/templates/mariadb/5.5/run.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +VOLUME_HOME="/var/lib/mysql" + +if [[ ! -d $VOLUME_HOME/mysql ]]; then + echo "=> An empty or uninitialized MariaDB volume is detected in $VOLUME_HOME" + echo "=> Installing MariaDB ..." + mysql_install_db > /dev/null 2>&1 + echo "=> Done!" + /home/init_user.sh +else + echo "=> Using an existing volume of MariaDB" +fi + +exec mysqld_safe diff --git a/templates/mariadb/README.md b/templates/mariadb/README.md new file mode 100755 index 0000000..151a682 --- /dev/null +++ b/templates/mariadb/README.md @@ -0,0 +1,67 @@ +docker-mariadb +==================== + +Base docker image to run a MariaDB database server + +MariaDB version +--------------- + + + +Usage +----- + +To create the image `scores/mariadb`, execute the following command on the tutum-docker-mariadb folder: + + docker build -t scores/mariadb . + +To run the image and bind to port 3306: + + docker run -d -p 3306:3306 scores/mariadb + +The first time that you run your container, a new user `admin` with all privileges +will be created in MariaDB with a random password. To get the password, check the logs +of the container by running: + + docker logs + +You will see an output like the following: + + ======================================================================== + You can now connect to this MariaDB Server using: + + mysql -uadmin -pxVN33tWOhM3u -h -P + + Please remember to change the above password as soon as possible! + MariaDB user 'root' has no password but only allows local connections + ======================================================================== + + +In this case, `xVN33tWOhM3u` is the password assigned to the `admin` user. + +Done! + + +Setting a specific password for the admin account +------------------------------------------------- + +If you want to use a preset password instead of a random generated one, you can +set the environment variable `MARIADB_PASS` to your specific password when running the container: + + docker run -d -p 3306:3306 -e MARIADB_PASS="mypass" scores/mariadb + + +Mounting the database file volume from other containers +------------------------------------------------------ + +One way to persist the database data is to store database files in another container. +To do so, first create a container that holds database files: + + docker run -d -v /var/lib/mysql --name db_vol -p 22:22 tutum/ubuntu-trusty + +This will create a new ssh-enabled container and use its folder `/var/lib/mysql` to store MariaDB database files. +You can specify any name of the container by using `--name` option, which will be used in next step. + +After this you can start your MariaDB image using volumes in the container created above (put the name of container in `--volumes-from`) + + docker run -d --volumes-from db_vol -p 3306:3306 scores/mariadb diff --git a/templates/mariadb/config/default.my.cnf.txt b/templates/mariadb/config/default.my.cnf.txt new file mode 100755 index 0000000..85037b8 --- /dev/null +++ b/templates/mariadb/config/default.my.cnf.txt @@ -0,0 +1,62 @@ +[mysqld] +# +# * Fine Tuning +# +max_connections = 100 +connect_timeout = 5 +wait_timeout = 7200 +max_allowed_packet = 16M +thread_cache_size = 128 +join_buffer_size = 64M +sort_buffer_size = 64M +bulk_insert_buffer_size = 256M +tmp_table_size = 16G +max_heap_table_size = 16G + +# +# * MyISAM +# +myisam_recover = BACKUP +key_buffer_size = 4G +table_open_cache = 1000 +table_definition_cache = 2000 +concurrent_insert = 2 +low_priority_updates = 1 +read_buffer_size = 64M +read_rnd_buffer_size = 64M +myisam_sort_buffer_size = 512M +myisam_repair_threads = 4 + +# +# * Aria +# +aria_repair_threads = 4 + +# +# * Query Cache Configuration +# +query_cache_limit = 4M +query_cache_size = 64M +query_cache_min_res_unit = 4K +query_cache_type = 1 + +# +# * InnoDB +# +innodb_log_file_size = 48M +innodb_buffer_pool_size = 256M +innodb_log_buffer_size = 8M +innodb_file_per_table = 1 +innodb_open_files = 400 +innodb_io_capacity = 400 +innodb_flush_method = O_DIRECT + +# +# * Logging +# +#log-queries-not-using-indexes +#log-slow-admin-statements +slow_query_log = 0 +slow_query_log_file = /var/lib/mysql/slow.log +long_query_time = 10 + diff --git a/templates/mariadb/config/master.my.cnf.txt b/templates/mariadb/config/master.my.cnf.txt new file mode 100755 index 0000000..d622186 --- /dev/null +++ b/templates/mariadb/config/master.my.cnf.txt @@ -0,0 +1,12 @@ +[mysqld] +# +# * Replication +# +server-id = 11 +binlog_format = MIXED +log_bin = /var/lib/mysql/log-bin +log_bin_index = /var/lib/mysql/log-bin.index +# not fab for performance, but safer +#sync_binlog = 1 +expire_logs_days = 10 +max_binlog_size = 1G diff --git a/templates/mariadb/config/slave.my.cnf.txt b/templates/mariadb/config/slave.my.cnf.txt new file mode 100755 index 0000000..f323a62 --- /dev/null +++ b/templates/mariadb/config/slave.my.cnf.txt @@ -0,0 +1,76 @@ +[mysqld] +# +# * Replication +# +server-id = 112 +binlog_format = MIXED +log_bin = /var/lib/mysql/log-bin +log_bin_index = /var/lib/mysql/log-bin.index +# not fab for performance, but safer +#sync_binlog = 1 +expire_logs_days = 10 +max_binlog_size = 1G +# slaves +relay_log = /var/lib/mysql/relay-bin +relay_log_index = /var/lib/mysql/relay-bin.index +relay_log_info_file = /var/lib/mysql/relay-bin.info +#log_slave_updates +#read_only +slave_compressed_protocol = 1 +slave_exec_mode = IDEMPOTENT +slave-skip-errors = 1062 + + +# Replication table +replicate-do-db=backoffice +replicate-wild-do-table=backoffice.% +replicate-do-db=boamp +replicate-wild-do-table=boamp.% +replicate-do-db=bopi +replicate-wild-do-table=bopi.% +replicate-do-db=bottin +replicate-wild-do-table=bottin.% +replicate-do-db=ciblage +replicate-wild-do-table=ciblage.% +replicate-do-db=execution +replicate-wild-do-table=execution.% +replicate-do-db=facturation +replicate-wild-do-table=facturation.% +replicate-do-db=histobodacc +replicate-wild-do-table=histobodacc.% +replicate-do-db=historiques +replicate-wild-do-table=historiques.% +replicate-do-db=insee +replicate-wild-do-table=insee.% +replicate-do-db=jo +replicate-wild-do-table=jo.% +replicate-do-db=modelisation +replicate-wild-do-table=modelisation.% +replicate-do-db=npaipp +replicate-wild-do-table=npaipp.% +replicate-do-db=octde +replicate-wild-do-table=octde.% +replicate-do-db=phpcrawl +replicate-wild-do-table=phpcrawl.% +replicate-do-db=phplist +replicate-wild-do-table=phplist.% +replicate-do-db=pollutions +replicate-wild-do-table=pollutions.% +replicate-do-db=presse +replicate-wild-do-table=presse.% +replicate-do-db=recuptables +replicate-wild-do-table=recuptables.% +replicate-do-db=sante +replicate-wild-do-table=sante.% +replicate-do-db=sdv1 +replicate-wild-do-table=sdv1.% +replicate-do-db=sugarcrm +replicate-wild-do-table=sugarcrm.% +replicate-do-db=telephonie +replicate-wild-do-table=telephonie.% +replicate-do-db=tmp +replicate-wild-do-table=tmp.% +replicate-do-db=villes +replicate-wild-do-table=villes.% +replicate-do-db=webfiler +replicate-wild-do-table=webfiler.% \ No newline at end of file diff --git a/templates/mysql/5.5/Dockerfile b/templates/mysql/5.5/Dockerfile new file mode 100755 index 0000000..dd12a2f --- /dev/null +++ b/templates/mysql/5.5/Dockerfile @@ -0,0 +1,33 @@ +FROM ubuntu:14.04 + +# Add MySQL configuration +ADD my.cnf /etc/mysql/conf.d/my.cnf + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && \ + apt-get -yq install mysql-server-5.5 pwgen && \ + rm /etc/mysql/conf.d/mysqld_safe_syslog.cnf && \ + if [ ! -f /usr/share/mysql/my-default.cnf ] ; then cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf; fi && \ + mysql_install_db > /dev/null 2>&1 && \ + touch /var/lib/mysql/.EMPTY_DB && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +# Add MySQL scripts +ADD sql_import.sh /sql_import.sh +ADD run.sh /run.sh +RUN chmod 775 /home/*.sh + +ENV MYSQL_USER=admin \ + MYSQL_PASS=**Random** \ + REPLICATION_MASTER=**False** \ + REPLICATION_SLAVE=**False** \ + REPLICATION_USER=replica \ + REPLICATION_PASS=replica \ + ON_CREATE_DB=**False** + +# Add VOLUMEs to allow backup of config and databases +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 +CMD ["/run.sh"] diff --git a/templates/mysql/5.5/docker-compose.yml b/templates/mysql/5.5/docker-compose.yml new file mode 100755 index 0000000..b153c3b --- /dev/null +++ b/templates/mysql/5.5/docker-compose.yml @@ -0,0 +1,4 @@ +bigdata: + image: scores/mysql:5.5 + environment: + MYSQL_PASS: "**ChangeMe**" diff --git a/templates/mysql/5.5/my.cnf b/templates/mysql/5.5/my.cnf new file mode 100755 index 0000000..02fe8be --- /dev/null +++ b/templates/mysql/5.5/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +bind-address=0.0.0.0 +# http://www.percona.com/blog/2008/05/31/dns-achilles-heel-mysql-installation/ +skip_name_resolve +#server-id +#log-bin diff --git a/templates/mysql/5.5/run.sh b/templates/mysql/5.5/run.sh new file mode 100755 index 0000000..e68c883 --- /dev/null +++ b/templates/mysql/5.5/run.sh @@ -0,0 +1,186 @@ +#!/bin/bash + +set -m +set -e + +VOLUME_HOME="/var/lib/mysql" +CONF_FILE="/etc/mysql/conf.d/my.cnf" +LOG="/var/log/mysql/error.log" + +# Set permission of config file +chmod 644 ${CONF_FILE} + +StartMySQL () +{ + /usr/bin/mysqld_safe > /dev/null 2>&1 & + # Time out in 1 minute + LOOP_LIMIT=60 + for (( i=0 ; ; i++ )); do + if [ ${i} -eq ${LOOP_LIMIT} ]; then + echo "Time out. Error log is shown as below:" + tail -n 100 ${LOG} + exit 1 + fi + echo "=> Waiting for confirmation of MySQL service startup, trying ${i}/${LOOP_LIMIT} ..." + sleep 1 + mysql -uroot -e "status" > /dev/null 2>&1 && break + done +} + +CreateMySQLUser() +{ + if [ "$MYSQL_PASS" = "**Random**" ]; then + unset MYSQL_PASS + fi + + PASS=${MYSQL_PASS:-$(pwgen -s 12 1)} + _word=$( [ ${MYSQL_PASS} ] && echo "preset" || echo "random" ) + echo "=> Creating MySQL user ${MYSQL_USER} with ${_word} password" + + mysql -uroot -e "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '$PASS'" + mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_USER}'@'%' WITH GRANT OPTION" + echo "=> Done!" + echo "========================================================================" + echo "You can now connect to this MySQL Server using:" + echo "" + echo " mysql -u$MYSQL_USER -p$PASS -h -P" + echo "" + echo "Please remember to change the above password as soon as possible!" + echo "MySQL user 'root' has no password but only allows local connections" + echo "========================================================================" +} + +OnCreateDB() +{ + if [ "$ON_CREATE_DB" = "**False**" ]; then + unset ON_CREATE_DB + else + echo "Creating MySQL database ${ON_CREATE_DB}" + mysql -uroot -e "CREATE DATABASE IF NOT EXISTS ${ON_CREATE_DB};" + echo "Database created!" + fi + +} + +ImportSql() +{ + for FILE in ${STARTUP_SQL}; do + echo "=> Importing SQL file ${FILE}" + mysql -uroot < "${FILE}" + done +} + +# Main +if [ ${REPLICATION_MASTER} == "**False**" ]; then + unset REPLICATION_MASTER +fi + +if [ ${REPLICATION_SLAVE} == "**False**" ]; then + unset REPLICATION_SLAVE +fi + +# Initialize empty data volume and create MySQL user +if [[ ! -d $VOLUME_HOME/mysql ]]; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME" + echo "=> Installing MySQL ..." + if [ ! -f /usr/share/mysql/my-default.cnf ] ; then + cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + mysql_install_db || exit 1 + touch /var/lib/mysql/.EMPTY_DB + echo "=> Done!" +else + echo "=> Using an existing volume of MySQL" +fi + +# Set MySQL REPLICATION - MASTER +if [ -n "${REPLICATION_MASTER}" ]; then + echo "=> Configuring MySQL replication as master (1/2) ..." + if [ ! -f /replication_set.1 ]; then + RAND="$(date +%s | rev | cut -c 1-2)$(echo ${RANDOM})" + echo "=> Writting configuration file '${CONF_FILE}' with server-id=${RAND}" + sed -i "s/^#server-id.*/server-id = ${RAND}/" ${CONF_FILE} + sed -i "s/^#log-bin.*/log-bin = mysql-bin/" ${CONF_FILE} + touch /replication_set.1 + else + echo "=> MySQL replication master already configured, skip" + fi +fi + +# Set MySQL REPLICATION - SLAVE +if [ -n "${REPLICATION_SLAVE}" ]; then + echo "=> Configuring MySQL replication as slave (1/2) ..." + if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ] && [ -n "${MYSQL_PORT_3306_TCP_PORT}" ]; then + if [ ! -f /replication_set.1 ]; then + RAND="$(date +%s | rev | cut -c 1-2)$(echo ${RANDOM})" + echo "=> Writting configuration file '${CONF_FILE}' with server-id=${RAND}" + sed -i "s/^#server-id.*/server-id = ${RAND}/" ${CONF_FILE} + sed -i "s/^#log-bin.*/log-bin = mysql-bin/" ${CONF_FILE} + touch /replication_set.1 + else + echo "=> MySQL replication slave already configured, skip" + fi + else + echo "=> Cannot configure slave, please link it to another MySQL container with alias as 'mysql'" + exit 1 + fi +fi + + +echo "=> Starting MySQL ..." +StartMySQL +tail -F $LOG & + +# Create admin user and pre create database +if [ -f /var/lib/mysql/.EMPTY_DB ]; then + echo "=> Creating admin user ..." + CreateMySQLUser + OnCreateDB + rm /var/lib/mysql/.EMPTY_DB +fi + + +# Import Startup SQL +if [ -n "${STARTUP_SQL}" ]; then + if [ ! -f /sql_imported ]; then + echo "=> Initializing DB with ${STARTUP_SQL}" + ImportSql + touch /sql_imported + fi +fi + +# Set MySQL REPLICATION - MASTER +if [ -n "${REPLICATION_MASTER}" ]; then + echo "=> Configuring MySQL replication as master (2/2) ..." + if [ ! -f /replication_set.2 ]; then + echo "=> Creating a log user ${REPLICATION_USER}:${REPLICATION_PASS}" + mysql -uroot -e "CREATE USER '${REPLICATION_USER}'@'%' IDENTIFIED BY '${REPLICATION_PASS}'" + mysql -uroot -e "GRANT REPLICATION SLAVE ON *.* TO '${REPLICATION_USER}'@'%'" + mysql -uroot -e "reset master" + echo "=> Done!" + touch /replication_set.2 + else + echo "=> MySQL replication master already configured, skip" + fi +fi + +# Set MySQL REPLICATION - SLAVE +if [ -n "${REPLICATION_SLAVE}" ]; then + echo "=> Configuring MySQL replication as slave (2/2) ..." + if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ] && [ -n "${MYSQL_PORT_3306_TCP_PORT}" ]; then + if [ ! -f /replication_set.2 ]; then + echo "=> Setting master connection info on slave" + mysql -uroot -e "CHANGE MASTER TO MASTER_HOST='${MYSQL_PORT_3306_TCP_ADDR}',MASTER_USER='${MYSQL_ENV_REPLICATION_USER}',MASTER_PASSWORD='${MYSQL_ENV_REPLICATION_PASS}',MASTER_PORT=${MYSQL_PORT_3306_TCP_PORT}, MASTER_CONNECT_RETRY=30" + mysql -uroot -e "start slave" + echo "=> Done!" + touch /replication_set.2 + else + echo "=> MySQL replication slave already configured, skip" + fi + else + echo "=> Cannot configure slave, please link it to another MySQL container with alias as 'mysql'" + exit 1 + fi +fi + +fg diff --git a/templates/mysql/5.5/sql-slaveusers.sql b/templates/mysql/5.5/sql-slaveusers.sql new file mode 100755 index 0000000..0659e8d --- /dev/null +++ b/templates/mysql/5.5/sql-slaveusers.sql @@ -0,0 +1,51 @@ +/* Rambouillet*/ + +CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'scores'; +GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION; + +CREATE USER 'root'@'192.168.3.%' IDENTIFIED BY 'zsu1amtj'; +GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.3.%' WITH GRANT OPTION; + +CREATE USER 'cacti'@'192.168.3.%' IDENTIFIED BY 'zsu1amtj'; +GRANT PROCESS, SUPER ON *.* TO 'cacti'@'192.168.3.%'; + +CREATE USER 'repl'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.3.%' IDENTIFIED BY 'scores'; + +CREATE USER 'backoffice'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'backoffice'@'192.168.3.%'; +CREATE USER 'batchuser'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'batchuser'@'192.168.3.%'; +CREATE USER 'ciblage'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'ciblage'@'192.168.3.%'; +CREATE USER 'sphinx'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'sphinx'@'192.168.3.%'; +CREATE USER 'wsuser'@'192.168.3.%' IDENTIFIED BY 'wspass2012'; +GRANT ALL ON *.* TO 'wsuser'@'192.168.3.%'; +CREATE USER 'sugarcrm'@'192.168.3.%' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'sugarcrm'@'192.168.3.%'; + +FLUSH PRIVILEGES; + +/* sd-48233 195.154.170.169 */ + +CREATE USER 'root'@'78.31.45.206' IDENTIFIED BY 'zsu1amtj'; +GRANT ALL PRIVILEGES ON *.* TO 'root'@'78.31.45.206' WITH GRANT OPTION; + +CREATE USER 'wsuser'@'78.31.45.206' IDENTIFIED BY 'wspass2012'; +GRANT SELECT ON *.* TO 'wsuser'@'78.31.45.206'; + +CREATE USER 'backoffice'@'195.154.251.56' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'backoffice'@'195.154.251.56'; +CREATE USER 'batchuser'@'195.154.251.56' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'batchuser'@'195.154.251.56'; +CREATE USER 'ciblage'@'195.154.251.56' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'ciblage'@'195.154.251.56'; +CREATE USER 'sphinx'@'195.154.251.56' IDENTIFIED BY 'indexer'; +GRANT ALL ON *.* TO 'sphinx'@'195.154.251.56'; +CREATE USER 'wsuser'@'195.154.251.56' IDENTIFIED BY 'wspass2012'; +GRANT ALL ON *.* TO 'wsuser'@'195.154.251.56'; +CREATE USER 'sugarcrm'@'195.154.251.56' IDENTIFIED BY 'scores'; +GRANT ALL ON *.* TO 'sugarcrm'@'195.154.251.56'; + +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/templates/mysql/5.5/sql_import.sh b/templates/mysql/5.5/sql_import.sh new file mode 100755 index 0000000..995e6c9 --- /dev/null +++ b/templates/mysql/5.5/sql_import.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [[ $# -ne 3 ]]; then + echo "Usage: $0 " + exit 1 +fi + +echo "=> Starting MySQL Server" +/usr/bin/mysqld_safe > /dev/null 2>&1 & +PID=$! + +RET=1 +while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + mysql -u"$1" -p"$2" -e "status" > /dev/null 2>&1 +RET=$? +done + +echo " Started with PID ${PID}" + +echo "=> Importing SQL file" +mysql -u"$1" -p"$2" < "$3" + +echo "=> Stopping MySQL Server" +mysqladmin -u"$1" -p"$2" shutdown + +echo "=> Done!" diff --git a/templates/mysql/5.6/Dockerfile b/templates/mysql/5.6/Dockerfile new file mode 100755 index 0000000..b0fb5f2 --- /dev/null +++ b/templates/mysql/5.6/Dockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:14.04 + +# Add MySQL configuration +ADD my.cnf /etc/mysql/conf.d/my.cnf +ADD mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + +RUN apt-get update && \ + apt-get -yq install mysql-server-5.6 pwgen && \ + rm -rf /var/lib/apt/lists/* && \ + rm /etc/mysql/conf.d/mysqld_safe_syslog.cnf && \ + if [ ! -f /usr/share/mysql/my-default.cnf ] ; then cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf; fi && \ + mysql_install_db > /dev/null 2>&1 && \ + touch /var/lib/mysql/.EMPTY_DB && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +# Add MySQL scripts +ADD import_sql.sh /import_sql.sh +ADD run.sh /run.sh + +ENV MYSQL_USER=admin \ + MYSQL_PASS=**Random** \ + ON_CREATE_DB=**False** \ + REPLICATION_MASTER=**False** \ + REPLICATION_SLAVE=**False** \ + REPLICATION_USER=replica \ + REPLICATION_PASS=replica + +# Add VOLUMEs to allow backup of config and databases +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 +CMD ["/run.sh"] diff --git a/templates/mysql/5.6/docker-compose.yml b/templates/mysql/5.6/docker-compose.yml new file mode 100755 index 0000000..6854cd1 --- /dev/null +++ b/templates/mysql/5.6/docker-compose.yml @@ -0,0 +1,4 @@ +db: + image: tutum/mysql:5.6 + environment: + MYSQL_PASS: "**ChangeMe**" diff --git a/templates/mysql/5.6/import_sql.sh b/templates/mysql/5.6/import_sql.sh new file mode 100755 index 0000000..995e6c9 --- /dev/null +++ b/templates/mysql/5.6/import_sql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [[ $# -ne 3 ]]; then + echo "Usage: $0 " + exit 1 +fi + +echo "=> Starting MySQL Server" +/usr/bin/mysqld_safe > /dev/null 2>&1 & +PID=$! + +RET=1 +while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + mysql -u"$1" -p"$2" -e "status" > /dev/null 2>&1 +RET=$? +done + +echo " Started with PID ${PID}" + +echo "=> Importing SQL file" +mysql -u"$1" -p"$2" < "$3" + +echo "=> Stopping MySQL Server" +mysqladmin -u"$1" -p"$2" shutdown + +echo "=> Done!" diff --git a/templates/mysql/5.6/my.cnf b/templates/mysql/5.6/my.cnf new file mode 100755 index 0000000..02fe8be --- /dev/null +++ b/templates/mysql/5.6/my.cnf @@ -0,0 +1,6 @@ +[mysqld] +bind-address=0.0.0.0 +# http://www.percona.com/blog/2008/05/31/dns-achilles-heel-mysql-installation/ +skip_name_resolve +#server-id +#log-bin diff --git a/templates/mysql/5.6/mysqld_charset.cnf b/templates/mysql/5.6/mysqld_charset.cnf new file mode 100755 index 0000000..2c9c4f1 --- /dev/null +++ b/templates/mysql/5.6/mysqld_charset.cnf @@ -0,0 +1,7 @@ +[mysqld] +character_set_server=utf8 +character_set_filesystem=utf8 +collation-server=utf8_general_ci +init-connect='SET NAMES utf8' +init_connect='SET collation_connection = utf8_general_ci' +skip-character-set-client-handshake \ No newline at end of file diff --git a/templates/mysql/5.6/run.sh b/templates/mysql/5.6/run.sh new file mode 100755 index 0000000..fcc5e78 --- /dev/null +++ b/templates/mysql/5.6/run.sh @@ -0,0 +1,187 @@ +#!/bin/bash + +set -m +set -e + +VOLUME_HOME="/var/lib/mysql" +CONF_FILE="/etc/mysql/conf.d/my.cnf" +LOG="/var/log/mysql/error.log" + +# Set permission of config file +chmod 644 ${CONF_FILE} +chmod 644 /etc/mysql/conf.d/mysqld_charset.cnf + +StartMySQL () +{ + /usr/bin/mysqld_safe > /dev/null 2>&1 & + # Time out in 1 minute + LOOP_LIMIT=60 + for (( i=0 ; ; i++ )); do + if [ ${i} -eq ${LOOP_LIMIT} ]; then + echo "Time out. Error log is shown as below:" + tail -n 100 ${LOG} + exit 1 + fi + echo "=> Waiting for confirmation of MySQL service startup, trying ${i}/${LOOP_LIMIT} ..." + sleep 1 + mysql -uroot -e "status" > /dev/null 2>&1 && break + done +} + +CreateMySQLUser() +{ + if [ "$MYSQL_PASS" = "**Random**" ]; then + unset MYSQL_PASS + fi + + PASS=${MYSQL_PASS:-$(pwgen -s 12 1)} + _word=$( [ ${MYSQL_PASS} ] && echo "preset" || echo "random" ) + echo "=> Creating MySQL user ${MYSQL_USER} with ${_word} password" + + mysql -uroot -e "CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '$PASS'" + mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO '${MYSQL_USER}'@'%' WITH GRANT OPTION" + echo "=> Done!" + echo "========================================================================" + echo "You can now connect to this MySQL Server using:" + echo "" + echo " mysql -u$MYSQL_USER -p$PASS -h -P" + echo "" + echo "Please remember to change the above password as soon as possible!" + echo "MySQL user 'root' has no password but only allows local connections" + echo "========================================================================" +} + +OnCreateDB() +{ + if [ "$ON_CREATE_DB" = "**False**" ]; then + unset ON_CREATE_DB + else + echo "Creating MySQL database ${ON_CREATE_DB}" + mysql -uroot -e "CREATE DATABASE IF NOT EXISTS ${ON_CREATE_DB};" + echo "Database created!" + fi + +} + +ImportSql() +{ + for FILE in ${STARTUP_SQL}; do + echo "=> Importing SQL file ${FILE}" + mysql -uroot < "${FILE}" + done +} + +# Main +if [ ${REPLICATION_MASTER} == "**False**" ]; then + unset REPLICATION_MASTER +fi + +if [ ${REPLICATION_SLAVE} == "**False**" ]; then + unset REPLICATION_SLAVE +fi + +# Initialize empty data volume and create MySQL user +if [[ ! -d $VOLUME_HOME/mysql ]]; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME" + echo "=> Installing MySQL ..." + if [ ! -f /usr/share/mysql/my-default.cnf ] ; then + cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + mysql_install_db || exit 1 + touch /var/lib/mysql/.EMPTY_DB + echo "=> Done!" +else + echo "=> Using an existing volume of MySQL" +fi + +# Set MySQL REPLICATION - MASTER +if [ -n "${REPLICATION_MASTER}" ]; then + echo "=> Configuring MySQL replication as master (1/2) ..." + if [ ! -f /replication_set.1 ]; then + RAND="$(date +%s | rev | cut -c 1-2)$(echo ${RANDOM})" + echo "=> Writting configuration file '${CONF_FILE}' with server-id=${RAND}" + sed -i "s/^#server-id.*/server-id = ${RAND}/" ${CONF_FILE} + sed -i "s/^#log-bin.*/log-bin = mysql-bin/" ${CONF_FILE} + touch /replication_set.1 + else + echo "=> MySQL replication master already configured, skip" + fi +fi + +# Set MySQL REPLICATION - SLAVE +if [ -n "${REPLICATION_SLAVE}" ]; then + echo "=> Configuring MySQL replication as slave (1/2) ..." + if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ] && [ -n "${MYSQL_PORT_3306_TCP_PORT}" ]; then + if [ ! -f /replication_set.1 ]; then + RAND="$(date +%s | rev | cut -c 1-2)$(echo ${RANDOM})" + echo "=> Writting configuration file '${CONF_FILE}' with server-id=${RAND}" + sed -i "s/^#server-id.*/server-id = ${RAND}/" ${CONF_FILE} + sed -i "s/^#log-bin.*/log-bin = mysql-bin/" ${CONF_FILE} + touch /replication_set.1 + else + echo "=> MySQL replication slave already configured, skip" + fi + else + echo "=> Cannot configure slave, please link it to another MySQL container with alias as 'mysql'" + exit 1 + fi +fi + + +echo "=> Starting MySQL ..." +StartMySQL +tail -F $LOG & + +# Create admin user and pre create database +if [ -f /var/lib/mysql/.EMPTY_DB ]; then + echo "=> Creating admin user ..." + CreateMySQLUser + OnCreateDB + rm /var/lib/mysql/.EMPTY_DB +fi + + +# Import Startup SQL +if [ -n "${STARTUP_SQL}" ]; then + if [ ! -f /sql_imported ]; then + echo "=> Initializing DB with ${STARTUP_SQL}" + ImportSql + touch /sql_imported + fi +fi + +# Set MySQL REPLICATION - MASTER +if [ -n "${REPLICATION_MASTER}" ]; then + echo "=> Configuring MySQL replication as master (2/2) ..." + if [ ! -f /replication_set.2 ]; then + echo "=> Creating a log user ${REPLICATION_USER}:${REPLICATION_PASS}" + mysql -uroot -e "CREATE USER '${REPLICATION_USER}'@'%' IDENTIFIED BY '${REPLICATION_PASS}'" + mysql -uroot -e "GRANT REPLICATION SLAVE ON *.* TO '${REPLICATION_USER}'@'%'" + mysql -uroot -e "reset master" + echo "=> Done!" + touch /replication_set.2 + else + echo "=> MySQL replication master already configured, skip" + fi +fi + +# Set MySQL REPLICATION - SLAVE +if [ -n "${REPLICATION_SLAVE}" ]; then + echo "=> Configuring MySQL replication as slave (2/2) ..." + if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ] && [ -n "${MYSQL_PORT_3306_TCP_PORT}" ]; then + if [ ! -f /replication_set.2 ]; then + echo "=> Setting master connection info on slave" + mysql -uroot -e "CHANGE MASTER TO MASTER_HOST='${MYSQL_PORT_3306_TCP_ADDR}',MASTER_USER='${MYSQL_ENV_REPLICATION_USER}',MASTER_PASSWORD='${MYSQL_ENV_REPLICATION_PASS}',MASTER_PORT=${MYSQL_PORT_3306_TCP_PORT}, MASTER_CONNECT_RETRY=30" + mysql -uroot -e "start slave" + echo "=> Done!" + touch /replication_set.2 + else + echo "=> MySQL replication slave already configured, skip" + fi + else + echo "=> Cannot configure slave, please link it to another MySQL container with alias as 'mysql'" + exit 1 + fi +fi + +fg diff --git a/templates/mysql/README.md b/templates/mysql/README.md new file mode 100755 index 0000000..f897039 --- /dev/null +++ b/templates/mysql/README.md @@ -0,0 +1,164 @@ +tutum-docker-mysql +================== + +[![Deploy to Tutum](https://s.tutum.co/deploy-to-tutum.svg)](https://dashboard.tutum.co/stack/deploy/) + +Base docker image to run a MySQL database server + + +MySQL version +------------- + +Different versions are built from different folders. If you want to use MariaDB, please check our `tutum/mariadb` image: https://github.com/tutumcloud/tutum-docker-mariadb + + +Usage +----- + +To create the image `tutum/mysql`, execute the following command on the tutum-mysql folder: + + docker build -t tutum/mysql 5.5/ + +To run the image and bind to port 3306: + + docker run -d -p 3306:3306 tutum/mysql + +The first time that you run your container, a new user `admin` with all privileges +will be created in MySQL with a random password. To get the password, check the logs +of the container by running: + + docker logs + +You will see an output like the following: + + ======================================================================== + You can now connect to this MySQL Server using: + + mysql -uadmin -p47nnf4FweaKu -h -P + + Please remember to change the above password as soon as possible! + MySQL user 'root' has no password but only allows local connections. + ======================================================================== + +In this case, `47nnf4FweaKu` is the password allocated to the `admin` user. + +Remember that the `root` user has no password, but it's only accessible from within the container. + +You can now test your deployment: + + mysql -uadmin -p + +Done! + + +Setting a specific password for the admin account +------------------------------------------------- + +If you want to use a preset password instead of a random generated one, you can +set the environment variable `MYSQL_PASS` to your specific password when running the container: + + docker run -d -p 3306:3306 -e MYSQL_PASS="mypass" tutum/mysql + +You can now test your deployment: + + mysql -uadmin -p"mypass" + +The admin username can also be set via the `MYSQL_USER` environment variable. + + + +Creating a database on container creation +------------------------------------------------- + +If you want a database to be created inside the container when you start it up +for the first time you can set the environment variable `ON_CREATE_DB` to a string +that names the database. + + docker run -d -p 3306:3306 -e ON_CREATE_DB="newdatabase" tutum/mysql + + +Mounting the database file volume +--------------------------------- + +In order to persist the database data, you can mount a local folder from the host +on the container to store the database files. To do so: + + docker run -d -v /path/in/host:/var/lib/mysql tutum/mysql /bin/bash -c "/usr/bin/mysql_install_db" + +This will mount the local folder `/path/in/host` inside the docker in `/var/lib/mysql` (where MySQL will store the database files by default). `mysql_install_db` creates the initial database structure. + +Remember that this will mean that your host must have `/path/in/host` available when you run your docker image! + +After this you can start your MySQL image, but this time using `/path/in/host` as the database folder: + + docker run -d -p 3306:3306 -v /path/in/host:/var/lib/mysql tutum/mysql + + +Mounting the database file volume from other containers +------------------------------------------------------ + +Another way to persist the database data is to store database files in another container. +To do so, first create a container that holds database files: + + docker run -d -v /var/lib/mysql --name db_vol -p 22:22 tutum/ubuntu-trusty + +This will create a new ssh-enabled container and use its folder `/var/lib/mysql` to store MySQL database files. +You can specify any name of the container by using `--name` option, which will be used in next step. + +After this you can start your MySQL image using volumes in the container created above (put the name of container in `--volumes-from`) + + docker run -d --volumes-from db_vol -p 3306:3306 tutum/mysql + + +Migrating an existing MySQL Server +---------------------------------- + +In order to migrate your current MySQL server, perform the following commands from your current server: + +To dump your databases structure: + + mysqldump -u -p --opt -d -B > /tmp/dbserver_schema.sql + +To dump your database data: + + mysqldump -u -p --quick --single-transaction -t -n -B > /tmp/dbserver_data.sql + +To import a SQL backup which is stored for example in the folder `/tmp` in the host, run the following: + + sudo docker run -d -v /tmp:/tmp tutum/mysql /bin/bash -c "/import_sql.sh /tmp/" + +Also, you can start the new database initializing it with the SQL file: + + sudo docker run -d -v /path/in/host:/var/lib/mysql -e STARTUP_SQL="/tmp/" tutum/mysql + +Where `` and `` are the database username and password set earlier and `` is the name of the SQL file to be imported. + + +Replication - Master/Slave +------------------------- +To use MySQL replication, please set environment variable `REPLICATION_MASTER`/`REPLICATION_SLAVE` to `true`. Also, on master side, you may want to specify `REPLICATION_USER` and `REPLICATION_PASS` for the account to perform replication, the default value is `replica:replica` + +Examples: +- Master MySQL +- + docker run -d -e REPLICATION_MASTER=true -e REPLICATION_PASS=mypass -p 3306:3306 --name mysql tutum/mysql + +- Example on Slave MySQL: +- + docker run -d -e REPLICATION_SLAVE=true -p 3307:3306 --link mysql:mysql tutum/mysql + +Now you can access port `3306` and `3307` for the master/slave MySQL. + +Environment variables +--------------------- + +`MYSQL_USER`: Set a specific username for the admin account (default 'admin'). + +`MYSQL_PASS`: Set a specific password for the admin account. + +`STARTUP_SQL`: Defines one or more SQL scripts separated by spaces to initialize the database. Note that the scripts must be inside the container, so you may need to mount them. + +Compatibility Issues +-------------------- + +- Volume created by MySQL 5.6 cannot be used in MySQL 5.5 Images or MariaDB images. diff --git a/templates/mysql/test.sh b/templates/mysql/test.sh new file mode 100755 index 0000000..745ed01 --- /dev/null +++ b/templates/mysql/test.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -e + +echo "=> Building mysql 5.5 image" +docker build -t mysql-5.5 5.5/ + +echo "=> Testing if mysql is running on 5.5" +docker run -d -p 13306:3306 -e MYSQL_USER="user" -e MYSQL_PASS="test" mysql-5.5; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P13306 ping | grep -c "mysqld is alive" + +echo "=> Testing replication on mysql 5.5" +docker run -d -e MYSQL_USER=user -e MYSQL_PASS=test -e REPLICATION_MASTER=true -e REPLICATION_USER=repl -e REPLICATION_PASS=repl -p 13307:3306 --name mysql55master mysql-5.5; sleep 10 +docker run -d -e MYSQL_USER=user -e MYSQL_PASS=test -e REPLICATION_SLAVE=true -p 13308:3306 --link mysql55master:mysql mysql-5.5; sleep 10 +docker logs mysql55master | grep "repl:repl" +mysql -uuser -ptest -h127.0.0.1 -P13307 -e "show master status\G;" | grep "mysql-bin.*" +mysql -uuser -ptest -h127.0.0.1 -P13308 -e "show slave status\G;" | grep "Slave_IO_Running.*Yes" +mysql -uuser -ptest -h127.0.0.1 -P13308 -e "show slave status\G;" | grep "Slave_SQL_Running.*Yes" + +echo "=> Testing avolume on mysql 5.5" +mkdir vol55 +docker run --name mysql55.1 -d -p 13309:3306 -e MYSQL_USER="user" -e MYSQL_PASS="test" -v $(pwd)/vol55:/var/lib/mysql mysql-5.5; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P13309 ping | grep -c "mysqld is alive" +docker stop mysql55.1 +docker run -d -p 13310:3306 -v $(pwd)/vol55:/var/lib/mysql mysql-5.5; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P13310 ping | grep -c "mysqld is alive" + +echo "=> Building mysql 5.6 image" +docker build -t mysql-5.6 5.6/ + +echo "=> Testing if mysql is running on 5.6" +docker run -d -p 23306:3306 -e MYSQL_USER="user" -e MYSQL_PASS="test" mysql-5.6; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P13307 ping | grep -c "mysqld is alive" + +echo "=> Testing replication on mysql 5.6" +docker run -d -e MYSQL_USER=user -e MYSQL_PASS=test -e REPLICATION_MASTER=true -e REPLICATION_USER=repl -e REPLICATION_PASS=repl -p 23307:3306 --name mysql56master mysql-5.6; sleep 10 +docker run -d -e MYSQL_USER=user -e MYSQL_PASS=test -e REPLICATION_SLAVE=true -p 23308:3306 --link mysql56master:mysql mysql-5.6; sleep 10 +docker logs mysql56master | grep "repl:repl" +mysql -uuser -ptest -h127.0.0.1 -P23307 -e "show master status\G;" | grep "mysql-bin.*" +mysql -uuser -ptest -h127.0.0.1 -P23308 -e "show slave status\G;" | grep "Slave_IO_Running.*Yes" +mysql -uuser -ptest -h127.0.0.1 -P23308 -e "show slave status\G;" | grep "Slave_SQL_Running.*Yes" + +echo "=> Testing volume on mysql 5.6" +mkdir vol56 +docker run --name mysql56.1 -d -p 23309:3306 -e MYSQL_USER="user" -e MYSQL_PASS="test" -v $(pwd)/vol56:/var/lib/mysql mysql-5.6; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P23309 ping | grep -c "mysqld is alive" +docker stop mysql56.1 +docker run -d -p 23310:3306 -v $(pwd)/vol56:/var/lib/mysql mysql-5.6; sleep 10 +mysqladmin -uuser -ptest -h127.0.0.1 -P23310 ping | grep -c "mysqld is alive" + +echo "=>Done" diff --git a/templates/sphinxsearch/Dockerfile b/templates/sphinxsearch/Dockerfile new file mode 100755 index 0000000..74460a4 --- /dev/null +++ b/templates/sphinxsearch/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:14.04 + +ENV TERM xterm +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get -y install software-properties-common && add-apt-repository ppa:builds/sphinxsearch-rel22 && \ + apt-get update && apt-get -y upgrade && \ + apt-get -y install nano supervisor mariadb-client libstemmer0d sphinxsearch logrotate && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ + echo "Europe/Paris" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata + +ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf +ADD logrotate-sphinxsearch /etc/logrotate.d/sphinxsearch +ADD cron-sphinxsearch /etc/cron.d/sphinxsearch + +# Add cli to run +ADD run.sh /home/run.sh +RUN chmod 775 /home/*.sh + +ADD sdsphinx.tar.gz /home/ +RUN cp /home/sdsphinx/config/sphinx.conf /etc/sphinxsearch/sphinx.conf && \ + mkdir -p /var/lib/sphinxsearch/log && mkdir -p /var/lib/sphinxsearch/idx && \ + chmod 775 /home/sdsphinx/indexer/*.sh + +# Add VOLUMEs +VOLUME ["/etc/cron.d", "/etc/sphinxsearch", "/var/lib/sphinxsearch"] + +# Environnement variables +ENV MYSQL_HOST=192.168.3.30 \ + MYSQL_USER=sphinx \ + MYSQL_PASS=indexer \ + SLAVE=0 \ + INDEX_ACT=0 \ + INDEX_CIBLAGE=0 \ + INDEX_DIR=0 \ + INDEX_ENT=0 \ + INDEX_DIR=0 \ + INDEX_HISTO=0 + +EXPOSE 9306 9312 +CMD ["/usr/bin/supervisord"] diff --git a/templates/sphinxsearch/README b/templates/sphinxsearch/README new file mode 100755 index 0000000..ecbaf34 --- /dev/null +++ b/templates/sphinxsearch/README @@ -0,0 +1,50 @@ +Sphinx Search Engine in Docker +============================== + +Build +----- +docker build -t scores/sphinxsearch:version . + + +Launch +------ + +Exemple d'un fichier docker-compose.yml + +sphinx: + container_name: sphinx + image: scores/sphinxsearch + ports: + - "9306:9306" + - "9312:9312" + mem_limit: 17196646400 + volumes: + - /media/disk02/sphinxsearch/data:/var/lib/sphinxsearch + log_driver: "json-file" + log_opt: + max-size: "500m" + max-file: "9" + environment: + MYSQL_HOST: 192.168.78.249 + MYSQL_USER: sphinx + MYSQL_PASS: indexer + SLAVE: 1 + INDEX_ACT: 1 + INDEX_CIBLAGE: 1 + INDEX_DIR: 1 + INDEX_ENT: 1 + INDEX_DIR: 1 + INDEX_HISTO: 1 + + +Configuration crontab +--------------------- + +Find the volume where crontab is store <...>/cron.d/sphinxsearch + +Uncomment the lines for which there must be an execution + +docker-compose stop sphinx +docker-compose start sphinx + + diff --git a/templates/sphinxsearch/cron-sphinxsearch b/templates/sphinxsearch/cron-sphinxsearch new file mode 100755 index 0000000..5df2393 --- /dev/null +++ b/templates/sphinxsearch/cron-sphinxsearch @@ -0,0 +1,13 @@ +# +# --- Lancement de l'indexation sphinx +# + +# --- Master Configuration +#01 12,18,23 * * * root /home/sdsphinx/indexer/indexer-act.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 +#01 */1 * * * root /home/sdsphinx/indexer/indexer-dir.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 +#01 */1 * * * root /home/sdsphinx/indexer/indexer-ent.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 + +# --- Slave Configuration +#01 12,18,23 * * * root /home/sdsphinx/indexer/indexer-act.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 +#01 */1 * * * root /home/sdsphinx/indexer/slave-dir.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 +#01 */1 * * * root /home/sdsphinx/indexer/slave-ent.sh >> /var/lib/sphinxsearch/log/cron.log 2>&1 \ No newline at end of file diff --git a/templates/sphinxsearch/logrotate-sphinxsearch b/templates/sphinxsearch/logrotate-sphinxsearch new file mode 100755 index 0000000..884fe7d --- /dev/null +++ b/templates/sphinxsearch/logrotate-sphinxsearch @@ -0,0 +1,10 @@ +/var/lib/sphinxsearch/log/query.log +/var/lib/sphinxsearch/log/indexer.log +{ + rotate 7 + weekly + missingok + notifempty + delaycompress + compress +} \ No newline at end of file diff --git a/templates/sphinxsearch/run.sh b/templates/sphinxsearch/run.sh new file mode 100755 index 0000000..4fa55d9 --- /dev/null +++ b/templates/sphinxsearch/run.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +VOLUME_HOME="/var/lib/sphinxsearch" + +# --- Configure +if [[ ! -f sphinx.conf ]]; then + touch sphinx.init.conf + touch sphinx.conf + + if [ ${INDEX_ACT} -eq 1 ]; then + cat /home/sdsphinx/config/act.conf >> sphinx.init.conf + cat /home/sdsphinx/config/act.conf >> sphinx.conf + fi + if [ ${INDEX_CIBLAGE} -eq 1 ]; then + cat /home/sdsphinx/config/ciblage.conf >> sphinx.init.conf + if [ ${SLAVE} -eq 1 ]; then + cat /home/sdsphinx/config/ciblage.conf >> sphinx.conf + else + cat /home/sdsphinx/config/ciblagetmp.conf >> sphinx.conf + fi + fi + if [ ${INDEX_DIR} -eq 1 ]; then + cat /home/sdsphinx/config/dir.conf >> sphinx.init.conf + if [ ${SLAVE} -eq 1 ]; then + cat /home/sdsphinx/config/dir.conf >> sphinx.conf + else + cat /home/sdsphinx/config/dirtmp.conf >> sphinx.conf + fi + fi + if [ ${INDEX_ENT} -eq 1 ]; then + cat /home/sdsphinx/config/ent.conf >> sphinx.init.conf + if [ ${SLAVE} -eq 1 ]; then + cat /home/sdsphinx/config/ent.conf >> sphinx.conf + else + cat /home/sdsphinx/config/enttmp.conf >> sphinx.conf + fi + cp -v /home/sdsphinx/config/stopwords-ent.txt /etc/sphinxsearch/ + cp -v /home/sdsphinx/config/wordforms-ent.txt /etc/sphinxsearch/ + fi + if [ ${INDEX_HISTO} -eq 1 ]; then + cat /home/sdsphinx/config/histo.conf >> sphinx.init.conf + cat /home/sdsphinx/config/histo.conf >> sphinx.conf + fi + + # --- Assign vars + sed -i -e "s/sql_host = ENV_MYSQLHOST/sql_host = $MYSQL_HOST/" sphinx*.conf + sed -i -e "s/sql_user = ENV_MYSQLUSER/sql_user = $MYSQL_USER/" sphinx*.conf + sed -i -e "s/sql_pass = ENV_MYSQLPASS/sql_pass = $MYSQL_PASS/" sphinx*.conf + + sed -i -e "s/MYSQL_HOST=ENV_MYSQLHOST/MYSQL_HOST=$MYSQL_HOST/" /home/sdsphinx/indexer/*.sh + sed -i -e "s/MYSQL_USER=ENV_MYSQLUSER/MYSQL_USER=$MYSQL_USER/" /home/sdsphinx/indexer/*.sh + sed -i -e "s/MYSQL_PASS=ENV_MYSQLPASS/MYSQL_PASS=$MYSQL_PASS/" /home/sdsphinx/indexer/*.sh + + cat sphinx.init.conf /home/sdsphinx/config/sphinx.conf > /etc/sphinxsearch/sphinx.init.conf + cat sphinx.conf /home/sdsphinx/config/sphinx.conf > /etc/sphinxsearch/sphinx.conf +fi + +# --- Init +if [[ ! -d $VOLUME_HOME/idx ]]; then + echo "=> An empty or uninitialized SPHINXSEARCH volume is detected in $VOLUME_HOME" + mkdir -p /var/lib/sphinxsearch/log && mkdir -p /var/lib/sphinxsearch/idx + echo "=> Creation index ..." + /usr/bin/indexer --config /etc/sphinxsearch/sphinx.init.conf --all + echo "=> Done!" +else + echo "=> Using an existing volume of SphinxSearch" +fi + +exec /usr/bin/searchd --nodetach \ No newline at end of file diff --git a/templates/sphinxsearch/sdsphinx.tar.gz b/templates/sphinxsearch/sdsphinx.tar.gz new file mode 100755 index 0000000000000000000000000000000000000000..5f820da2a51a721dd12cad2750172597f33034ca GIT binary patch literal 18190 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