From a44ac45376711adfc20e2dd764f79330dbbe90c9 Mon Sep 17 00:00:00 2001 From: Ian Blenke Date: Sat, 13 Sep 2014 23:04:20 -0400 Subject: [PATCH] Added ianblenke/docker-huginn as docker/ subdirectory, moved Dockerfile out of the root and renamed as Dockerfile.rbenv --- docker/Dockerfile | 29 ++++++ Dockerfile => docker/Dockerfile.rbenv | 0 docker/Makefile | 2 + docker/README.md | 124 +++++++++++++++++++++++ docker/scripts/init | 136 ++++++++++++++++++++++++++ docker/scripts/setup | 39 ++++++++ 6 files changed, 330 insertions(+) create mode 100644 docker/Dockerfile rename Dockerfile => docker/Dockerfile.rbenv (100%) create mode 100644 docker/Makefile create mode 100644 docker/README.md create mode 100755 docker/scripts/init create mode 100755 docker/scripts/setup diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..9ff1bdf1 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:14.04 +MAINTAINER ian@blenke.com + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update && \ + apt-get install -y software-properties-common && \ + add-apt-repository -y ppa:git-core/ppa && \ + add-apt-repository -y ppa:brightbox/ruby-ng && \ + apt-get update && \ + apt-get install -y build-essential checkinstall postgresql-client \ + git-core mysql-server redis-server python2.7 python-docutils \ + libmysqlclient-dev libpq-dev zlib1g-dev libyaml-dev libssl-dev \ + libgdbm-dev libreadline-dev libncurses5-dev libffi-dev \ + libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev \ + ruby2.1 ruby2.1-dev supervisor && \ + gem install --no-ri --no-rdoc bundler && \ + rm -rf /var/lib/apt/lists/* + +ADD scripts/ /scripts +RUN chmod 755 /scripts/setup /scripts/init + +RUN /scripts/setup + +VOLUME /var/lib/mysql + +EXPOSE 5000 + +CMD ["/scripts/init"] + diff --git a/Dockerfile b/docker/Dockerfile.rbenv similarity index 100% rename from Dockerfile rename to docker/Dockerfile.rbenv diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 00000000..35cfc85a --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,2 @@ +build: + docker build -t cantino/huginn . diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..3219837d --- /dev/null +++ b/docker/README.md @@ -0,0 +1,124 @@ +Huginn for docker with multiple container linkage +================================================= + +This image runs a linkable [Huginn](https://github.com/cantino/huginn) instance. + +There is an automated build repository on docker hub for [cantino/huginn](https://registry.hub.docker.com/builds/github/cantino/huginn/). + +This was patterned after [sameersbn/gitlab](https://registry.hub.docker.com/u/sameersbn/gitlab) by [ianblenke/huginn](http://github.com/ianblenke/huginn), and imported here for official generation of a docker hub auto-build image. + +The scripts/init script generates a .env file containing the variables as passed as per normal Huginn documentation. +The same environment variables that would be used for Heroku PaaS deployment are used by this script. + +The scripts/init script is aware of mysql and postgres linked containers through the environment variables: + + MYSQL_PORT_3306_TCP_ADDR + MYSQL_PORT_3306_TCP_PORT + +and + + POSTGRESQL_PORT_5432_TCP_ADDR + POSTGRESQL_PORT_5432_TCP_PORT + +Its recommended to use an image that allows you to create a database via environmental variables at docker run, like `paintedfox / postgresql` or `centurylink / mysql`, so the db is populated when this script runs. + +If you do not link a database container, a built-in mysql database will be started. +There is an exported docker volume of /var/lib/mysql to allow persistence of that mysql database. + +Additionally, the database variables may be overridden from the above as per the standard Huginn documentation: + + DATABASE_ADAPTER #(must be either 'postgres' or 'mysql2') + DATABASE_HOST + DATABASE_PORT + +This script will run database migrations (rake db:migrate) which should be idempotent. + +It will also seed the database (rake db:seed) unless this is defined: + + DO_NOT_SEED + +This same seeding initially defines the "admin" user with a default password of "password" as per the standard Huginn documentation. + +If you do not wish to have the default 6 agents, you will want to set the above environment variable after your initially deploy, otherwise they will be added automatically the next time a container pointing at the database is spun up. + +The CMD launches Huginn via the scripts/init script. This may become the ENTRYPOINT later. It does take under a minute for Huginn to come up. Use environmental variables that match your DB's creds to ensure it works. + +## Usage + +Simple stand-alone usage: + + docker run -it -p 5000:5000 cantino/huginn + +To link to another mysql container, for example: + + docker run --rm --name newcentury_mysql -p 3306 \ + -e MYSQL_DATABASE=huginn \ + -e MYSQL_USER=huginn \ + -e MYSQL_PASSWORD=somethingsecret \ + -e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \ + cantino/huginn + docker run --rm --name huginn --link newcentury_mysql:MYSQL -p 5000:5000 \ + -e DATABASE_NAME=huginn \ + -e DATABASE_USER=huginn \ + -e DATABASE_PASSWORD=somethingsecret \ + cantino/huginn + +To link to another container named 'postgres': + + docker run --rm --name huginn --link POSTGRES:mysql -p 5000:5000 -e "DATABASE_USER=huginn" -e "DATABASE_PASSWORD=pass@word" cantino/huginn + +## Environment Variables + +Other Huginn 12factored environment variables of note, as generated and put into the .env file as per Huginn documentation: + + APP_SECRET_TOKEN=${APP_SECRET_TOKEN:-CHANGEME} + DOMAIN=${HUGINN_HOST:-localhost}:${PORT:-5000} + ${ASSET_HOST:+ASSET_HOST=${ASSET_HOST}} + DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2} + DATABASE_ENCODING=${DATABASE_ENCODING:-utf8} + DATABASE_RECONNECT=${DATABASE_RECONNECT:-true} + DATABASE_NAME=${DATABASE_NAME:-huginn} + DATABASE_POOL=${DATABASE_POOL:-5} + DATABASE_USERNAME=${DATABASE_USERNAME:-root} + DATABASE_PASSWORD="${DATABASE_PASSWORD}" + DATABASE_PORT=${DATABASE_PORT:-3306} + DATABASE_HOST=${DATABASE_HOST:-localhost} + DATABASE_PORT=${DATABASE_PORT:-3306} + ${DATABASE_SOCKET:+DATABASE_SOCKET=${DATABASE_SOCKET:-/tmp/mysql.sock}} + ${RAILS_ENV:+RAILS_ENV=${RAILS_ENV:-production}} + FORCE_SSL=${FORCE_SSL:-false} + INVITATION_CODE=${INVITATION_CODE:-try-huginn} + SMTP_DOMAIN=${SMTP_DOMAIM=-example.com} + SMTP_USER_NAME=${SMTP_USER_NAME:-you@gmail.com} + SMTP_PASSWORD=${SMTP_PASSWORD:-somepassword} + SMTP_SERVER=${SMTP_SERVER:-smtp.gmail.com} + SMTP_PORT=${SMTP_PORT:-587} + SMTP_AUTHENTICATION=${SMTP_AUTHENTICATION:-plain} + SMTP_ENABLE_STARTTLS_AUTO=${SMTP_ENABLE_STARTTLS_AUTO:-true} + EMAIL_FROM_ADDRESS=${EMAIL_FROM_ADDRESS:-huginn@example.com} + AGENT_LOG_LENGTH=${AGENT_LOG_LENGTH:-200} + AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-your aws access key id}" + AWS_ACCESS_KEY="${AWS_ACCESS_KEY:-your aws access key}" + AWS_SANDBOX=${AWS_SANDBOX:-false} + FARADAY_HTTP_BACKEND=${FARADAY_HTTP_BACKEND:-typhoeus} + DEFAULT_HTTP_USER_AGENT="${DEFAULT_HTTP_USER_AGENT:-Huginn - https://github.com/cantino/huginn}" + ALLOW_JSONPATH_EVAL=${ALLOW_JSONPATH_EVAL:-false} + ENABLE_INSECURE_AGENTS=${ENABLE_INSECURE_AGENTS:-false} + ${USE_GRAPHVIZ_DOT:+USE_GRAPHVIZ_DOT=${USE_GRAPHVIZ_DOT:-dot}} + TIMEZONE="${TIMEZONE:-Pacific Time (US & Canada)}" + +The defaults used are the Huginn defaults as per the [.env.example](https://github.com/cantino/huginn/blob/master/.env.example) file. + +## Building on your own + +You don't need to do this on your own, because there is an [automated build](https://registry.hub.docker.com/u/cantino/huginn/) for this repository, but if you really want: + + docker build --rm=true --tag={yourname}/huginn . + +## Source + +The source is [available on GitHub](https://github.com/cantino/docker-huginn/). + +Please feel free to submit pull requests and/or fork at your leisure. + + diff --git a/docker/scripts/init b/docker/scripts/init new file mode 100755 index 00000000..f4a243aa --- /dev/null +++ b/docker/scripts/init @@ -0,0 +1,136 @@ +#!/bin/bash +set -e + +cd /app + +# is a mysql or postgresql database linked? +# requires that the mysql or postgresql containers have exposed +# port 3306 and 5432 respectively. +if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ]; then + DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2} + DATABASE_HOST=${DATABASE_HOST:-${MYSQL_PORT_3306_TCP_ADDR}} + DATABASE_PORT=${DATABASE_PORT:-${MYSQL_PORT_3306_TCP_PORT}} +elif [ -n "${POSTGRESQL_PORT_5432_TCP_ADDR}" ]; then + DATABASE_ADAPTER=${DATABASE_ADAPTER:-postgres} + DATABASE_HOST=${DATABASE_HOST:-${POSTGRESQL_PORT_5432_TCP_ADDR}} + DATABASE_PORT=${DATABASE_PORT:-${POSTGRESQL_PORT_5432_TCP_PORT}} +fi + +cat < /app/.env +APP_SECRET_TOKEN=${APP_SECRET_TOKEN:-CHANGEME} +DOMAIN=${DOMAIN:+${HUGINN_HOST:-localhost}:${PORT:-5000}} +${ASSET_HOST:+ASSET_HOST=${ASSET_HOST}} +DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2} +DATABASE_ENCODING=${DATABASE_ENCODING:-utf8} +DATABASE_RECONNECT=${DATABASE_RECONNECT:-true} +DATABASE_NAME=${DATABASE_NAME:-huginn} +DATABASE_POOL=${DATABASE_POOL:-5} +DATABASE_USERNAME=${DATABASE_USERNAME:-root} +DATABASE_PASSWORD="${DATABASE_PASSWORD}" +DATABASE_PORT=${DATABASE_PORT:-3306} +DATABASE_HOST=${DATABASE_HOST:-localhost} +DATABASE_PORT=${DATABASE_PORT:-3306} +${DATABASE_SOCKET:+DATABASE_SOCKET=${DATABASE_SOCKET:-/tmp/mysql.sock}} +${RAILS_ENV:+RAILS_ENV=${RAILS_ENV:-production}} +FORCE_SSL=${FORCE_SSL:-false} +INVITATION_CODE=${INVITATION_CODE:-try-huginn} +SMTP_DOMAIN=${SMTP_DOMAIM=-example.com} +SMTP_USER_NAME=${SMTP_USER_NAME:-you@gmail.com} +SMTP_PASSWORD=${SMTP_PASSWORD:-somepassword} +SMTP_SERVER=${SMTP_SERVER:-smtp.gmail.com} +SMTP_PORT=${SMTP_PORT:-587} +SMTP_AUTHENTICATION=${SMTP_AUTHENTICATION:-plain} +SMTP_ENABLE_STARTTLS_AUTO=${SMTP_ENABLE_STARTTLS_AUTO:-true} +EMAIL_FROM_ADDRESS=${EMAIL_FROM_ADDRESS:-huginn@example.com} +AGENT_LOG_LENGTH=${AGENT_LOG_LENGTH:-200} +AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-your aws access key id}" +AWS_ACCESS_KEY="${AWS_ACCESS_KEY:-your aws access key}" +AWS_SANDBOX=${AWS_SANDBOX:-false} +FARADAY_HTTP_BACKEND=${FARADAY_HTTP_BACKEND:-typhoeus} +DEFAULT_HTTP_USER_AGENT="${DEFAULT_HTTP_USER_AGENT:-Huginn - https://github.com/cantino/huginn}" +ALLOW_JSONPATH_EVAL=${ALLOW_JSONPATH_EVAL:-false} +ENABLE_INSECURE_AGENTS=${ENABLE_INSECURE_AGENTS:-false} +${USE_GRAPHVIZ_DOT:+USE_GRAPHVIZ_DOT=${USE_GRAPHVIZ_DOT:-dot}} +TIMEZONE="${TIMEZONE:-Pacific Time (US & Canada)}" +EOF +chmod ugo+r /app/.env +source /app/.env + +# use default port number if it is still not set +case "${DATABASE_ADAPTER}" in + mysql2) DATABASE_PORT=${DATABASE_PORT:-3306} ;; + postgres) DATABASE_PORT=${DATABASE_PORT:-5432} ;; + *) echo "Unsupported database adapter. Available adapters are mysql2, and postgres." && exit 1 ;; +esac + +# start supervisord +/usr/bin/supervisord -c /etc/supervisor/supervisord.conf + +# start mysql server if ${DATABASE_HOST} is localhost +if [ "${DATABASE_HOST}" == "localhost" ]; then + if [ "${DATABASE_ADAPTER}" == "postgres" ]; then + echo "DATABASE_ADAPTER 'postgres' is not supported internally. Please provide DATABASE_HOST." + exit 1 + fi + + # configure supervisord to start mysql (manual) + cat > /etc/supervisor/conf.d/mysqld.conf </dev/null + + # wait for mysql server to start (max 120 seconds) + timeout=120 + while ! mysqladmin -uroot ${DATABASE_PASSWORD:+-p$DATABASE_PASSWORD} status >/dev/null 2>&1 + do + timeout=$(expr $timeout - 1) + if [ $timeout -eq 0 ]; then + echo "Failed to start mysql server" + exit 1 + fi + sleep 1 + done + + if ! echo "USE ${DATABASE_NAME}" | mysql -uroot ${DATABASE_PASSWORD:+-p$DATABASE_PASSWORD} >/dev/null 2>&1; then + DB_INIT="yes" + echo "CREATE DATABASE IF NOT EXISTS \`${DATABASE_NAME}\` DEFAULT CHARACTER SET \`utf8\` COLLATE \`utf8_unicode_ci\`;" | mysql -uroot ${DATABASE_PASSWORD:+-p$DATABASE_PASSWORD} + echo "GRANT SELECT, LOCK TABLES, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON \`${DATABASE_NAME}\`.* TO 'root'@'localhost';" | mysql -uroot ${DATABASE_PASSWORD:+-p$DATABASE_PASSWORD} + fi +fi + +# Assuming we have a created database, run the migrations and seed it idempotently. +[ -z "${DO_NOT_MIGRATE}" ] && sudo -u huginn -EH bundle exec rake db:migrate +[ -z "${DO_NOT_SEED}" ] && sudo -u huginn -EH bundle exec rake db:seed + +[ -n "$INTENTIONALLY_SLEEP" ] && sleep $INTENTIONALLY_SLEEP + +# Fixup the Procfile and prepare the PORT +[ -z "${DO_NOT_RUN_JOBS}" ] && perl -pi -e 's/^jobs:/#jobs:/' /app/Procfile +perl -pi -e 's/rails server$/rails server -p \$PORT/' /app/Procfile +export PORT + +# Start huginn +sudo -u huginn -EH bundle exec foreman start + +# As the ENTRYPOINT script, when this exits the docker container will Exit. +exit 0 diff --git a/docker/scripts/setup b/docker/scripts/setup new file mode 100755 index 00000000..c36c4d3c --- /dev/null +++ b/docker/scripts/setup @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +# Initialize variables used by Huginn at installation time + +# Huginn is 12factor aware, embrace that fact for use inside of docker +ON_HEROKU=${ON_HEROKU:-true} + +# Shallow clone the huginn project repo +git clone --depth 1 https://github.com/cantino/huginn /app + +cd /app + +# add a huginn group and user +adduser --group huginn +adduser --disabled-login --ingroup huginn --gecos 'Huginn' --no-create-home --home /app huginn +adduser huginn sudo +passwd -d huginn + +# Change the ownership to huginn +chown -R huginn:huginn /app + +# create required tmp and log directories +sudo -u huginn -H mkdir -p tmp/pids tmp/cache tmp/sockets log +chmod -R u+rwX log tmp + +# install gems required by Huginn, use local cache if available +if [ -d "/scripts/cache" ]; then + mv /scripts/cache vendor/ + chown -R huginn:huginn vendor/cache +fi +sudo -u huginn -H bundle install --deployment --without development test + +# silence setlocale message (THANKS DEBIAN!) +cat > /etc/default/locale <