Browse Source

Add single process docker container

Dominik Sander 9 years ago
parent
commit
a5417fabf1

+ 16 - 0
docker/single-process/Dockerfile

@@ -0,0 +1,16 @@
+FROM ubuntu:14.04
+MAINTAINER Dominik Sander
+
+ADD scripts/prepare /scripts/prepare
+RUN /scripts/prepare
+
+ADD scripts/setup /scripts/setup
+RUN /scripts/setup
+
+WORKDIR /app
+
+ADD scripts/init /scripts/init
+
+EXPOSE 3000
+
+CMD ["/scripts/init"]

+ 94 - 0
docker/single-process/README.md

@@ -0,0 +1,94 @@
+Docker image for Huginn using the production environment and separate container for every process
+=================================================
+
+This image runs a linkable [Huginn](https://github.com/cantino/huginn) instance.
+
+It was inspired by the [official docker container for huginn](https://registry.hub.docker.com/u/cantino/huginn)
+
+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 `postgresql` or `mysql`, so the db is populated when this script runs.
+
+Additionally, the database variables may be overridden from the above as per the standard Huginn documentation:
+
+    DATABASE_ADAPTER #(must be either 'postgresql' 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 startup using docker compose (you need to daemonize with `-d` to persist the data):
+
+    cd docker/single-process
+    docker-compose up
+
+or if you like to use PostgreSQL:
+
+    docker-compose -f postgresql.yml up
+
+Manual startup and linking to a MySQL container:
+
+    docker run --name huginn_mysql \
+        -e MYSQL_DATABASE=huginn \
+        -e MYSQL_USER=huginn \
+        -e MYSQL_PASSWORD=somethingsecret \
+        -e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \
+        mysql
+
+    docker run --name huginn_web \
+        --link huginn_mysql:mysql \
+        -p 3000:3000 \
+        -e DATABASE_NAME=huginn \
+        -e DATABASE_USERNAME=huginn \
+        -e DATABASE_PASSWORD=somethingsecret \
+        dsander/huginn-single-process
+
+    docker run --name huginn_threaded \
+        --link huginn_mysql:mysql \
+        -e DATABASE_NAME=huginn \
+        -e DATABASE_USERNAME=huginn \
+        -e DATABASE_PASSWORD=somethingsecret \
+        dsander/huginn-single-process /scripts/init bin/threaded.rb
+
+## Environment Variables
+
+Other Huginn 12factored environment variables of note, as generated and put into the .env file as per Huginn documentation. All variables of the [.env.example](https://github.com/cantino/huginn/blob/master/.env.example) can be used to override the defaults which a read from the current `.env.example`.
+
+For variables in the .env.example that are commented out, the default is to not include that variable in the generated .env file.
+
+## Building on your own
+
+You don't need to do this on your own, but if you really want:
+
+    docker build --rm=true --tag={yourname}/huginn .
+
+## Source
+
+The source is [available on GitHub](https://github.com/cantino/huginn/docker/single-process/).
+
+Please feel free to submit pull requests and/or fork at your leisure.
+
+

+ 35 - 0
docker/single-process/docker-compose.yml

@@ -0,0 +1,35 @@
+mysqldata:
+  image: mysql
+  command: /bin/true
+
+mysql:
+  image: mysql
+  volumes_from:
+    - mysqldata
+  environment:
+    MYSQL_ROOT_PASSWORD: myrootpassword
+    MYSQL_DATABASE: huginn
+    MYSQL_USER: huginn
+    MYSQL_PASSWORD: myhuginnpassword
+
+huginn_web:
+  build: .
+  restart: always
+  extends:
+    file: environment.yml
+    service: huginn_base
+  ports:
+    - 3000:3000
+  links:
+    - mysql
+
+huginn_threaded:
+  build: .
+  restart: always
+  extends:
+    file: environment.yml
+    service: huginn_base
+  links:
+    - mysql
+  command: /scripts/init bin/threaded.rb
+

+ 7 - 0
docker/single-process/environment.yml

@@ -0,0 +1,7 @@
+huginn_base:
+  environment:
+    DATABASE_ADAPTER: mysql2
+    DATABASE_NAME: huginn
+    DATABASE_USERNAME: huginn
+    DATABASE_PASSWORD: myhuginnpassword
+    APP_SECRET_TOKEN: 3bd139f9186b31a85336bb89cd1a1337078921134b2f48e022fd09c234d764d3e19b018b2ab789c6e0e04a1ac9e3365116368049660234c2038dc9990513d49c

+ 72 - 0
docker/single-process/postgresql.yml

@@ -0,0 +1,72 @@
+postgresdata:
+  image: postgres
+  command: /bin/true
+
+postgres:
+  image: postgres
+  volumes_from:
+    - postgresdata
+  environment:
+    POSTGRES_PASSWORD: myhuginnpassword
+    POSTGRES_USER: huginn
+
+huginn_web:
+  build: .
+  restart: always
+  extends:
+    file: environment.yml
+    service: huginn_base
+  environment:
+    DATABASE_ADAPTER: postgresql
+  ports:
+    - 3000:3000
+  links:
+    - postgres
+
+huginn_threaded:
+  build: .
+  restart: always
+  extends:
+    file: environment.yml
+    service: huginn_base
+  environment:
+    DATABASE_ADAPTER: postgresql
+  links:
+    - postgres
+  command: /scripts/init bin/threaded.rb
+
+# huginn_schedule:
+#   build: .
+#   extends:
+#     file: environment.yml
+#     service: huginn_base
+#   environment:
+#     DATABASE_ADAPTER: postgresql
+#   links:
+#     - postgres
+#   command: /scripts/init bin/schedule.rb
+
+
+# huginn_twitter_stream:
+#   build: .
+#   extends:
+#     file: environment.yml
+#     service: huginn_base
+#   environment:
+#     DATABASE_ADAPTER: postgresql
+#   links:
+#     - postgres
+#   command: /scripts/init bin/twitter_stream.rb
+
+
+# huginn_dj1:
+#   build: .
+#   extends:
+#     file: environment.yml
+#     service: huginn_base
+#   environment:
+#     DATABASE_ADAPTER: postgresql
+#   links:
+#     - postgres
+#   command: /scripts/init script/delayed_job run
+

+ 57 - 0
docker/single-process/scripts/init

@@ -0,0 +1,57 @@
+#!/bin/bash
+set -e
+
+cd /app
+
+# Configure database based on linked container
+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}}
+  DATABASE_ENCODING=${DATABASE_ENCODING:-utf8mb4}
+elif [ -n "${POSTGRES_PORT_5432_TCP_ADDR}" ]; then
+  DATABASE_ADAPTER=${DATABASE_ADAPTER:-postgresql}
+  DATABASE_HOST=${DATABASE_HOST:-${POSTGRES_PORT_5432_TCP_ADDR}}
+  DATABASE_PORT=${DATABASE_PORT:-${POSTGRES_PORT_5432_TCP_PORT}}
+  DATABASE_ENCODING=utf8
+fi
+
+USE_GRAPHVIZ_DOT=${USE_GRAPHVIZ_DOT:-${USE_GRAPHVIZ_DOT:-dot}}
+
+# Default to the environment variable values set in .env.example
+IFS="="
+grep = /app/.env.example | sed -e 's/^#\([^ ]\)/\1/' | grep -v -e '^#' | \
+  while read var value ; do
+    eval "echo \"$var=\${$var:-\${HUGINN_$var-\$value}}\""
+  done | grep -v -e ^= > /app/.env
+
+eval "echo PORT=${PORT:-${PORT:-3000}}" >> .env
+eval "echo RAILS_ENV=${RAILS_ENV:-${RAILS_ENV:-production}}" >> .env
+eval "echo ON_HEROKU=true" >> .env
+eval "echo RAILS_SERVE_STATIC_FILES=true" >> .env
+
+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} ;;
+  postgresql) DATABASE_PORT=${DATABASE_PORT:-5432} ;;
+  *) echo "Unsupported database adapter. Available adapters are mysql2, and postgresql." && exit 1 ;;
+esac
+
+sudo -u huginn -H bundle install --without test development --path vendor/bundle
+
+if [ -z $1 ]; then
+  sudo -u huginn -H bundle exec rake db:create db:migrate RAILS_ENV=${RAILS_ENV}
+fi
+
+if [[ -z "${DO_NOT_SEED}" && -z $1 ]]; then
+  sudo -u huginn -H bundle exec rake db:seed RAILS_ENV=${RAILS_ENV}
+fi
+
+if [ -z $1 ]; then
+  exec sudo -u huginn -H bundle exec unicorn -c config/unicorn.rb
+else
+  exec sudo -u huginn -H bundle exec rails runner "$@" RAILS_ENV=${RAILS_ENV}
+fi

+ 43 - 0
docker/single-process/scripts/prepare

@@ -0,0 +1,43 @@
+#!/bin/bash
+set -e
+
+cat > /etc/dpkg/dpkg.cfg.d/01_nodoc <<EOF
+# Delete locales
+path-exclude=/usr/share/locale/*
+
+# Delete man pages
+path-exclude=/usr/share/man/*
+
+# Delete docs
+path-exclude=/usr/share/doc/*
+path-include=/usr/share/doc/*/copyright
+EOF
+
+cat > /etc/default/locale <<EOF
+LC_ALL=en_US.UTF-8
+LANG=en_US.UTF-8
+EOF
+
+export LC_ALL=C
+export DEBIAN_FRONTEND=noninteractive
+minimal_apt_get_install='apt-get install -y --no-install-recommends'
+
+apt-get update
+apt-get dist-upgrade -y --no-install-recommends
+$minimal_apt_get_install software-properties-common
+add-apt-repository -y ppa:brightbox/ruby-ng
+apt-get update
+$minimal_apt_get_install build-essential checkinstall git-core \
+  zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev \
+  libncurses5-dev libffi-dev libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev \
+  graphviz libgraphviz-dev \
+  libmysqlclient-dev libpq-dev libsqlite3-dev \
+  ruby2.2 ruby2.2-dev
+gem install --no-ri --no-rdoc bundler
+
+apt-get purge -y python3* rsyslog rsync manpages
+rm -rf /var/lib/apt/lists/*
+rm -rf /usr/share/doc/
+rm -rf /usr/share/man/
+rm -rf /usr/share/locale/
+rm -rf /var/log/*

+ 34 - 0
docker/single-process/scripts/setup

@@ -0,0 +1,34 @@
+#!/bin/bash
+set -e
+
+# add a huginn group and user
+adduser --group huginn
+adduser --disabled-login --ingroup huginn --gecos 'Huginn' --no-create-home --home /app huginn
+passwd -d huginn
+
+# Shallow clone the huginn project repo
+git clone --depth 1 https://github.com/cantino/huginn /app
+
+# Change the ownership to huginn
+chown -R huginn:huginn /app
+
+cd 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
+
+# HACK: We need a database connection to precompile the assets, use sqlite for that
+echo "gem 'sqlite3', '~> 1.3.11'" >> Gemfile
+sudo -u huginn -H RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=sqlite3 ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4
+sudo -u huginn -H RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=sqlite3 ON_HEROKU=true bundle exec rake assets:clean assets:precompile
+git checkout Gemfile
+
+# Bundle again to get rid of the sqlite3 gem
+sudo -u huginn -H ON_HEROKU=true DATABASE_ADAPTER=noop bundle install --without test development --path vendor/bundle
+
+# Configure the unicorn server
+mv config/unicorn.rb.example config/unicorn.rb
+sed -ri 's/^listen .*$/listen ENV["PORT"]/' config/unicorn.rb
+sed -ri 's/^stderr_path.*$//' config/unicorn.rb
+sed -ri 's/^stdout_path.*$//' config/unicorn.rb