Merge pull request #2112 from baip/master

Make Docker image runnable as non-root user
This commit is contained in:
Dominik Sander 2017-10-22 21:42:50 +02:00 committed by GitHub
commit 8054945593
15 changed files with 193 additions and 223 deletions

3
bin/docker_wrapper Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
chmod -R g=u . && docker "$@"

View file

@ -4,9 +4,9 @@ set -ev
docker pull $DOCKER_IMAGE docker pull $DOCKER_IMAGE
if [[ $DOCKER_IMAGE =~ "cantino" ]]; then if [[ $DOCKER_IMAGE =~ "cantino" ]]; then
docker build --build-arg OUTDATED_DOCKER_IMAGE_NAMESPACE='true' -t $DOCKER_IMAGE -f $DOCKERFILE . bin/docker_wrapper build --build-arg OUTDATED_DOCKER_IMAGE_NAMESPACE='true' -t $DOCKER_IMAGE -f $DOCKERFILE .
else else
docker build -t $DOCKER_IMAGE -f $DOCKERFILE . bin/docker_wrapper build -t $DOCKER_IMAGE -f $DOCKERFILE .
fi fi
if [[ -n "${DOCKER_USER}" && "${TRAVIS_PULL_REQUEST}" = 'false' && "${TRAVIS_BRANCH}" = "master" ]]; then if [[ -n "${DOCKER_USER}" && "${TRAVIS_PULL_REQUEST}" = 'false' && "${TRAVIS_BRANCH}" = "master" ]]; then

View file

@ -1,32 +1,36 @@
FROM ubuntu:14.04 FROM ubuntu:14.04
ADD docker/scripts/prepare /scripts/prepare COPY docker/scripts/prepare /scripts/
RUN /scripts/prepare RUN /scripts/prepare
ADD docker/multi-process/scripts/standalone-packages /scripts/standalone-packages COPY docker/multi-process/scripts/standalone-packages /scripts/
RUN /scripts/standalone-packages RUN /scripts/standalone-packages
WORKDIR /app WORKDIR /app
ADD ["Gemfile", "Gemfile.lock", "/app/"] COPY ["Gemfile", "Gemfile.lock", "/app/"]
ADD lib/gemfile_helper.rb /app/lib/ COPY lib/gemfile_helper.rb /app/lib/
ADD vendor/gems /app/vendor/gems COPY vendor/gems/ /app/vendor/gems/
RUN chown -R huginn:huginn /app && \ # Get rid of annoying "fatal: Not a git repository (or any of the parent directories): .git" messages
sudo -u huginn -H echo "gem 'sqlite3', '~> 1.3.11'" >> /app/Gemfile && \ RUN umask 002 && git init && \
sudo -u huginn -H LC_ALL=en_US.UTF-8 RAILS_ENV=production ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4 LC_ALL=en_US.UTF-8 RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=mysql2 ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4
COPY . /app
COPY ./ /app/
ARG OUTDATED_DOCKER_IMAGE_NAMESPACE=false ARG OUTDATED_DOCKER_IMAGE_NAMESPACE=false
ENV OUTDATED_DOCKER_IMAGE_NAMESPACE ${OUTDATED_DOCKER_IMAGE_NAMESPACE} ENV OUTDATED_DOCKER_IMAGE_NAMESPACE ${OUTDATED_DOCKER_IMAGE_NAMESPACE}
ADD ["docker/scripts/setup", "docker/scripts/setup_env", "docker/multi-process/scripts/init", "/scripts/"] RUN umask 002 && \
LC_ALL=en_US.UTF-8 RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=mysql2 ON_HEROKU=true bundle exec rake assets:clean assets:precompile && \
chmod g=u /app/.env.example /app/Gemfile.lock /app/config/ /app/tmp/
RUN /scripts/setup
VOLUME /var/lib/mysql
EXPOSE 3000 EXPOSE 3000
COPY ["docker/scripts/setup_env", "docker/multi-process/scripts/init", "/scripts/"]
CMD ["/scripts/init"] CMD ["/scripts/init"]
USER 1001
VOLUME /var/lib/mysql

View file

@ -3,9 +3,9 @@ Huginn for docker with multiple container linkage
This image runs a linkable [Huginn](https://github.com/huginn/huginn) instance. This image runs a linkable [Huginn](https://github.com/huginn/huginn) instance.
There is an automated build repository on docker hub for [huginn/huginn](https://hub.docker.com/r/huginn/huginn/builds/). There is an automated build repository on docker hub for [huginn/huginn](https://hub.docker.com/r/huginn/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. This was patterned after [sameersbn/gitlab](https://hub.docker.com/r/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 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 same environment variables that would be used for Heroku PaaS deployment are used by this script.
@ -55,16 +55,17 @@ Simple stand-alone usage (use only for testing/evaluation as it can not be updat
Use a volume to export the data of the internal mysql server: Use a volume to export the data of the internal mysql server:
docker run -it -p 3000:3000 -v /home/huginn/mysql-data:/var/lib/mysql huginn/huginn docker run --rm -it -p 3000:3000 -v /home/huginn/mysql-data:/var/lib/mysql huginn/huginn
To link to another mysql container, for example: To link to another mysql container, for example:
docker run --rm --name huginn_mysql \ docker run --name huginn_mysql \
-e MYSQL_DATABASE=huginn \ -e MYSQL_DATABASE=huginn \
-e MYSQL_USER=huginn \ -e MYSQL_USER=huginn \
-e MYSQL_PASSWORD=somethingsecret \ -e MYSQL_PASSWORD=somethingsecret \
-e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \ -e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \
mysql mysql
docker run --rm --name huginn \ docker run --rm --name huginn \
--link huginn_mysql:mysql \ --link huginn_mysql:mysql \
-p 3000:3000 \ -p 3000:3000 \
@ -78,6 +79,7 @@ To link to another container named 'postgres':
docker run --name huginn_postgres \ docker run --name huginn_postgres \
-e POSTGRES_PASSWORD=mysecretpassword \ -e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_USER=huginn -d postgres -e POSTGRES_USER=huginn -d postgres
docker run --rm --name huginn \ docker run --rm --name huginn \
--link huginn_postgres:postgres \ --link huginn_postgres:postgres \
-p 3000:3000 \ -p 3000:3000 \
@ -88,7 +90,8 @@ To link to another container named 'postgres':
The `docker/multi-process` folder also has a `docker-compose.yml` that allows for a sample database formation with a data volume container: The `docker/multi-process` folder also has a `docker-compose.yml` that allows for a sample database formation with a data volume container:
cd docker/multi-process ; docker-compose up cd docker/multi-process
docker-compose up
## Environment Variables ## Environment Variables
@ -100,14 +103,12 @@ In newer versions of Docker you are able to pass your own .env file in to the co
## Building on your own ## 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/huginn/huginn/) for this repository, but if you really want run this command in the Huginn root directory: You don't need to do this on your own, because there is an [automated build](https://hub.docker.com/r/huginn/huginn/) for this repository, but if you really want run this command in the Huginn root directory:
docker build --rm=true --tag={yourname}/huginn -f docker/multi-process/Dockerfile . bin/docker_wrapper build --rm=true --tag={yourname}/huginn -f docker/multi-process/Dockerfile .
## Source ## Source
The source is [available on GitHub](https://github.com/huginn/huginn/docker/multi-process/). The source is [available on GitHub](https://github.com/huginn/huginn/tree/master/docker/multi-process).
Please feel free to submit pull requests and/or fork at your leisure. Please feel free to submit pull requests and/or fork at your leisure.

View file

@ -1,69 +1,22 @@
#!/bin/bash #!/bin/bash
set -e set -e
export LC_ALL=en_US.UTF-8
cd /app cd /app
# Do we have a Rails secret yet?
# If not, generate one, but persist it for the container's lifetime.
if [ -z "$APP_SECRET_TOKEN" ] && grep -q ^APP_SECRET_TOKEN=REPLACE_ME_NOW .env.example; then
echo 'Generating random APP_SECRET_TOKEN.'
secret=$(dd if=/dev/urandom bs=36 count=1 | openssl base64)
sed -i.orig "s:REPLACE_ME_NOW:$secret:" .env.example
fi
# Cleanup any leftover pid file # Cleanup any leftover pid file
if [ -f /app/tmp/pids/server.pid ]; then if [ -f /app/tmp/pids/server.pid ]; then
rm /app/tmp/pids/server.pid rm /app/tmp/pids/server.pid
fi fi
# is a mysql or postgresql database linked? source /scripts/setup_env
# requires that the mysql or postgresql containers have exposed
# port 3306 and 5432 respectively. # Fixup the Procfile and prepare the PORT
if [[ -n "${MYSQL_PORT_3306_TCP_ADDR}" || ("${DATABASE_ADAPTER}" == "mysql2" && -n "${DATABASE_HOST}") ]]; then if [ -n "${DO_NOT_RUN_JOBS}" ]; then
DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2} sed -i -e 's/^jobs:/#jobs:/' /app/Procfile
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}" || "${DATABASE_ADAPTER}" == "postgresql" ]]; 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
else
START_MYSQL=${START_MYSQL:-true}
fi fi
USE_GRAPHVIZ_DOT=${HUGINN_USE_GRAPHVIZ_DOT:-${USE_GRAPHVIZ_DOT:-dot}} IP="${IP:-0.0.0.0}"
DATABASE_HOST=${HUGINN_DATABASE_HOST:-${DATABASE_HOST:-localhost}} sed -i -e "s/\${IP-0.0.0.0}/$IP/" -e "s/\${PORT-3000}/$PORT/" /app/Procfile
DATABASE_PORT=${HUGINN_DATABASE_PORT:-${DATABASE_PORT}}
DATABASE_ENCODING=${HUGINN_DATABASE_ENCODING:-${DATABASE_ENCODING}}
DATABASE_PASSWORD=${HUGINN_DATABASE_PASSWORD:-${DATABASE_PASSWORD:-password}}
DATABASE_NAME=${HUGINN_DATABASE_NAME:-${DATABASE_NAME:-huginn_production}}
RAILS_ENV=${HUGINN_RAILS_ENV:-${RAILS_ENV:-production}}
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 RAILS_ENV=${RAILS_ENV}" >> .env
eval "echo START_MYSQL=${START_MYSQL}" >> .env
echo "RAILS_LOG_TO_STDOUT=true" >> .env
echo "RAILS_SERVE_STATIC_FILES=true" >> .env
chmod ugo+r /app/.env
source /app/.env
sudo -u huginn -H -E bundle install --without test development --path vendor/bundle
# 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
# initialize supervisord config # initialize supervisord config
cat > /etc/supervisor/supervisord.conf <<EOF cat > /etc/supervisor/supervisord.conf <<EOF
@ -73,10 +26,9 @@ chmod=0700 ; sockef file mode (default 0700)
[supervisord] [supervisord]
nodaemon = true nodaemon = true
user = root
stdout_logfile = AUTO stdout_logfile = AUTO
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) pidfile=/app/tmp/pids/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC ; the below section must remain in the config file for RPC
@ -114,7 +66,7 @@ echo DATABASE_HOST=\${DATABASE_HOST}
# start mysql server if \${DATABASE_HOST} is the .env.example default # start mysql server if \${DATABASE_HOST} is the .env.example default
if [ "\${START_MYSQL}" = "true" ]; then if [ "\${START_MYSQL}" = "true" ]; then
echo "DATABASE_SOCKET=/var/run/mysqld/mysqld.sock" >> .env echo "DATABASE_SOCKET=/app/tmp/sockets/mysqld.sock" >> .env
if [ "\${DATABASE_ADAPTER}" = "postgresql" ]; then if [ "\${DATABASE_ADAPTER}" = "postgresql" ]; then
echo "DATABASE_ADAPTER 'postgresql' is not supported internally. Please provide DATABASE_HOST." echo "DATABASE_ADAPTER 'postgresql' is not supported internally. Please provide DATABASE_HOST."
exit 1 exit 1
@ -126,7 +78,6 @@ if [ "\${START_MYSQL}" = "true" ]; then
priority=20 priority=20
directory=/tmp directory=/tmp
command=/usr/bin/mysqld_safe command=/usr/bin/mysqld_safe
user=root
autostart=false autostart=false
autorestart=true autorestart=true
stdout_events_enabled=true stdout_events_enabled=true
@ -135,13 +86,10 @@ EOF
supervisorctl reread supervisorctl reread
supervisorctl add mysqld supervisorctl add mysqld
# fix permissions and ownership of /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
chmod 700 /var/lib/mysql
# initialize MySQL data directory # initialize MySQL data directory
if [ ! -d /var/lib/mysql/mysql ]; then if [ ! -d /var/lib/mysql/mysql ]; then
mysql_install_db --user=mysql mysql_install_db --user=\$(whoami) --datadir=/tmp/mysql
mv -f /tmp/mysql/* /var/lib/mysql/
fi fi
echo "Starting mysql server..." echo "Starting mysql server..."
@ -207,28 +155,20 @@ fi
# We may need to try and create a database # We may need to try and create a database
if [ -z "\${DO_NOT_CREATE_DATABASE}" ]; then if [ -z "\${DO_NOT_CREATE_DATABASE}" ]; then
sudo -u huginn -EH bundle exec rake db:create bundle exec rake db:create
fi fi
# Assuming we have a created database, run the migrations and seed it idempotently. # Assuming we have a created database, run the migrations and seed it idempotently.
if [ -z "\${DO_NOT_MIGRATE}" ]; then if [ -z "\${DO_NOT_MIGRATE}" ]; then
sudo -u huginn -EH bundle exec rake db:migrate bundle exec rake db:migrate
fi fi
if [ -z "\${DO_NOT_SEED}" ]; then if [ -z "\${DO_NOT_SEED}" ]; then
sudo -u huginn -EH bash -xc 'bundle exec rake db:seed &' bash -xc 'bundle exec rake db:seed &'
fi fi
# Fixup the Procfile and prepare the PORT
if [ -n "\${DO_NOT_RUN_JOBS}" ]; then
perl -pi -e 's/^jobs:/#jobs:/' /app/Procfile
fi
perl -pi -e 's/rails server -b0.0.0.0\$/rails server -b 0.0.0.0 -p \\\$PORT/' /app/Procfile
export PORT="\${PORT:-3000}"
# Start huginn # Start huginn
exec sudo -u huginn -EH bash -xc 'exec bundle exec foreman start' exec bundle exec foreman start
FOREMAN FOREMAN
chmod 755 /tmp/foreman.sh chmod 755 /tmp/foreman.sh

View file

@ -2,8 +2,18 @@ export DEBIAN_FRONTEND=noninteractive
apt-get update apt-get update
apt-get install -y python2.7 python-docutils mysql-server \ apt-get install -y python2.7 python-docutils mysql-server \
supervisor python-pip && \ supervisor python-pip && \
apt-get -y clean
pip install supervisor-stdout pip install supervisor-stdout
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
rm -rf /usr/share/doc/ rm -rf /usr/share/doc/
rm -rf /usr/share/man/ rm -rf /usr/share/man/
rm -rf /usr/share/locale/ rm -rf /usr/share/locale/
rm -rf /var/log/*
mkdir -p /var/log/supervisor /var/log/mysql
chgrp -R 0 /etc/supervisor /var/lib/mysql /var/log/supervisor /var/log/mysql
chmod -R g=u /etc/supervisor /var/lib/mysql /var/log/supervisor /var/log/mysql
sed -r -i /etc/mysql/my.cnf \
-e 's/^ *user *.+/user=1001/' \
-e 's#/var/run/mysqld/mysqld.sock#/app/tmp/sockets/mysqld.sock#' \
-e 's#/var/run/mysqld/mysqld.pid#/app/tmp/pids/mysqld.pid#'

View file

@ -33,16 +33,12 @@ update-locale LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8
gem install --no-ri --no-rdoc bundler gem install --no-ri --no-rdoc bundler
apt-get purge -y python3* rsyslog rsync manpages apt-get purge -y python3* rsyslog rsync manpages
apt-get -y clean
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
rm -rf /usr/share/doc/ rm -rf /usr/share/doc/
rm -rf /usr/share/man/ rm -rf /usr/share/man/
rm -rf /usr/share/locale/ rm -rf /usr/share/locale/
rm -rf /var/log/* rm -rf /var/log/*
# add a huginn group and user mkdir -p /app
adduser --group huginn chmod -R g=u /etc/passwd /app
adduser --disabled-login --ingroup huginn --gecos 'Huginn' --no-create-home --home /app huginn
passwd -d huginn
mkdir -p /app/lib/
mkdir -p /app/vendor/gems

View file

@ -1,42 +0,0 @@
#!/bin/bash
set -e
cd /app
export LC_ALL=en_US.UTF-8
# Ensure the huginn user has access to the required directories
sudo -u huginn -H mkdir -p tmp/pids tmp/cache tmp/sockets log
sudo -u huginn -H touch log/production.log
# Get rid of annoying "fatal: Not a git repository (or any of the parent directories): .git" messages
sudo -u huginn -H git init
# HACK: We need a database connection to precompile the assets, use sqlite for that
cp Gemfile Gemfile.bak
echo "gem 'sqlite3', '~> 1.3.11'" >> /app/Gemfile
RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=sqlite3 ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4
RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=sqlite3 ON_HEROKU=true bundle exec rake assets:clean assets:precompile
# Bundle again to get rid of the sqlite3 gem
cp Gemfile.bak Gemfile
RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=sqlite3 ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4
chown huginn:huginn Gemfile.lock
# 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
# Add ENV variables to .env.example which are not present in it but usable
cat >> /app/.env.example <<EOF
ASSET_HOST=
DEFAULT_SCENARIO_FILE=
RAILS_SERVE_STATIC_FILES=
SEED_EMAIL=
SEED_PASSWORD=
SEED_USERNAME=
SMTP_OPENSSL_CA_FILE=
SMTP_OPENSSL_CA_PATH=
SMTP_OPENSSL_VERIFY_MODE=
EOF

View file

@ -5,31 +5,90 @@ export LC_ALL=en_US.UTF-8
cd /app cd /app
# Configure database based on linked container export HOME=/app
if [ -n "${MYSQL_PORT_3306_TCP_ADDR}" ]; then if ! whoami &> /dev/null; then
DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2} if [ -w /etc/passwd ]; then
DATABASE_HOST=${DATABASE_HOST:-${MYSQL_PORT_3306_TCP_ADDR}} echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
DATABASE_PORT=${DATABASE_PORT:-${MYSQL_PORT_3306_TCP_PORT}} fi
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 fi
USE_GRAPHVIZ_DOT=${USE_GRAPHVIZ_DOT:-${USE_GRAPHVIZ_DOT:-dot}} # Do we have a Rails secret yet?
# If not, generate one, but persist it for the container's lifetime.
if [ -z "$APP_SECRET_TOKEN" ] && grep -q ^APP_SECRET_TOKEN=REPLACE_ME_NOW .env.example; then
echo 'Generating random APP_SECRET_TOKEN.'
secret=$(dd if=/dev/urandom bs=36 count=1 | openssl base64)
sed -i "s:REPLACE_ME_NOW!:$secret:" .env.example
fi
# 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}" || ("${DATABASE_ADAPTER}" == "mysql2" && -n "${DATABASE_HOST}") ]]; then
DATABASE_ADAPTER=${DATABASE_ADAPTER:-mysql2}
DATABASE_HOST=${DATABASE_HOST:-${MYSQL_PORT_3306_TCP_ADDR}}
DATABASE_PORT=${DATABASE_PORT:-${MYSQL_PORT_3306_TCP_PORT:-3306}}
DATABASE_ENCODING=${DATABASE_ENCODING:-utf8mb4}
elif [[ -n "${POSTGRES_PORT_5432_TCP_ADDR}" || ("${DATABASE_ADAPTER}" == "postgresql" && -n "${DATABASE_HOST}") ]]; then
DATABASE_ADAPTER=${DATABASE_ADAPTER:-postgresql}
DATABASE_HOST=${DATABASE_HOST:-${POSTGRES_PORT_5432_TCP_ADDR}}
DATABASE_PORT=${DATABASE_PORT:-${POSTGRES_PORT_5432_TCP_PORT:-5432}}
DATABASE_ENCODING=utf8
else
START_MYSQL=${START_MYSQL:-true}
fi
USE_GRAPHVIZ_DOT=${HUGINN_USE_GRAPHVIZ_DOT:-${USE_GRAPHVIZ_DOT:-dot}}
DATABASE_HOST=${HUGINN_DATABASE_HOST:-${DATABASE_HOST:-localhost}}
DATABASE_PORT=${HUGINN_DATABASE_PORT:-${DATABASE_PORT}}
DATABASE_ENCODING=${HUGINN_DATABASE_ENCODING:-${DATABASE_ENCODING}}
DATABASE_PASSWORD=${HUGINN_DATABASE_PASSWORD:-${DATABASE_PASSWORD:-password}}
DATABASE_NAME=${HUGINN_DATABASE_NAME:-${DATABASE_NAME:-huginn_production}}
RAILS_ENV=${HUGINN_RAILS_ENV:-${RAILS_ENV:-production}}
# Add ENV variables to .env.example which are not present in it but usable
cat >> /app/.env.example <<EOF
ASSET_HOST=
DEFAULT_SCENARIO_FILE=
RAILS_SERVE_STATIC_FILES=
SEED_EMAIL=
SEED_PASSWORD=
SEED_USERNAME=
SMTP_OPENSSL_CA_FILE=
SMTP_OPENSSL_CA_PATH=
SMTP_OPENSSL_VERIFY_MODE=
EOF
# Default to the environment variable values set in .env.example # Default to the environment variable values set in .env.example
IFS="=" IFS="="
grep = /app/.env.example | sed -e 's/^#\([^ ]\)/\1/' | grep -v -e '^#' | \ sed -n -r -e 's/^#?([A-Za-z0-9_]+ *=.*)/\1/p' /app/.env.example | \
while read var value ; do while read var value ; do
eval "echo \"$var=\${$var:-\${HUGINN_$var-\$value}}\"" eval "echo \"$var=\${HUGINN_$var:-\${$var:-\$value}}\""
done | grep -v -e ^= > /app/.env done > /app/.env
eval "echo PORT=${PORT:-${PORT:-3000}}" >> .env PORT=${HUGINN_PORT:-${PORT:-3000}}
eval "echo RAILS_ENV=${RAILS_ENV:-${RAILS_ENV:-production}}" >> .env echo "PORT=$(echo $PORT|awk -F ':' '{print $NF}')" >> .env
eval "echo RAILS_LOG_TO_STDOUT=true" >> .env echo "RAILS_ENV=${RAILS_ENV}" >> .env
eval "echo RAILS_SERVE_STATIC_FILES=true" >> .env echo "RAILS_LOG_TO_STDOUT=true" >> .env
echo "RAILS_SERVE_STATIC_FILES=true" >> .env
echo "START_MYSQL=${START_MYSQL}" >> .env
chmod ugo+r /app/.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
bundle install --without test development --path vendor/bundle
# Configure the unicorn server
cp -a 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
sed -ri 's/^pid.*$//' config/unicorn.rb
mkdir -p tmp/pids tmp/cache tmp/sockets log

View file

@ -1,26 +1,30 @@
FROM ubuntu:14.04 FROM ubuntu:14.04
ADD docker/scripts/prepare /scripts/prepare COPY docker/scripts/prepare /scripts/
RUN /scripts/prepare RUN /scripts/prepare
WORKDIR /app WORKDIR /app
ADD ["Gemfile", "Gemfile.lock", "/app/"] COPY ["Gemfile", "Gemfile.lock", "/app/"]
ADD lib/gemfile_helper.rb /app/lib/ COPY lib/gemfile_helper.rb /app/lib/
ADD vendor/gems /app/vendor/gems COPY vendor/gems/ /app/vendor/gems/
RUN chown -R huginn:huginn /app && \ # Get rid of annoying "fatal: Not a git repository (or any of the parent directories): .git" messages
sudo -u huginn -H echo "gem 'sqlite3', '~> 1.3.11'" >> /app/Gemfile && \ RUN umask 002 && git init && \
sudo -u huginn -H LC_ALL=en_US.UTF-8 RAILS_ENV=production ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4 LC_ALL=en_US.UTF-8 RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=mysql2 ON_HEROKU=true bundle install --without test development --path vendor/bundle -j 4
COPY . /app
COPY ./ /app/
ARG OUTDATED_DOCKER_IMAGE_NAMESPACE=false ARG OUTDATED_DOCKER_IMAGE_NAMESPACE=false
ENV OUTDATED_DOCKER_IMAGE_NAMESPACE ${OUTDATED_DOCKER_IMAGE_NAMESPACE} ENV OUTDATED_DOCKER_IMAGE_NAMESPACE ${OUTDATED_DOCKER_IMAGE_NAMESPACE}
ADD ["docker/scripts/setup", "docker/scripts/setup_env", "docker/single-process/scripts/init", "/scripts/"] RUN umask 002 && \
LC_ALL=en_US.UTF-8 RAILS_ENV=production APP_SECRET_TOKEN=secret DATABASE_ADAPTER=mysql2 ON_HEROKU=true bundle exec rake assets:clean assets:precompile && \
RUN /scripts/setup chmod g=u /app/.env.example /app/Gemfile.lock /app/config/ /app/tmp/
EXPOSE 3000 EXPOSE 3000
COPY ["docker/scripts/setup_env", "docker/single-process/scripts/init", "/scripts/"]
CMD ["/scripts/init"] CMD ["/scripts/init"]
USER 1001

View file

@ -3,7 +3,7 @@ Docker image for Huginn using the production environment and separate container
This image runs a linkable [Huginn](https://github.com/huginn/huginn) instance. This image runs a linkable [Huginn](https://github.com/huginn/huginn) instance.
It was inspired by the [official docker container for huginn](https://registry.hub.docker.com/u/huginn/huginn) It was inspired by the [official docker container for huginn](https://hub.docker.com/r/huginn/huginn)
The scripts/init script generates a .env file containing the variables as passed as per normal Huginn documentation. 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 same environment variables that would be used for Heroku PaaS deployment are used by this script.
@ -60,7 +60,7 @@ Manual startup and linking to a MySQL container:
-e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \ -e MYSQL_ROOT_PASSWORD=somethingevenmoresecret \
mysql mysql
docker run --name huginn_web \ docker run --rm --name huginn_web \
--link huginn_mysql:mysql \ --link huginn_mysql:mysql \
-p 3000:3000 \ -p 3000:3000 \
-e DATABASE_NAME=huginn \ -e DATABASE_NAME=huginn \
@ -68,13 +68,23 @@ Manual startup and linking to a MySQL container:
-e DATABASE_PASSWORD=somethingsecret \ -e DATABASE_PASSWORD=somethingsecret \
huginn/huginn-single-process huginn/huginn-single-process
docker run --name huginn_threaded \ docker run --rm --name huginn_threaded \
--link huginn_mysql:mysql \ --link huginn_mysql:mysql \
-e DATABASE_NAME=huginn \ -e DATABASE_NAME=huginn \
-e DATABASE_USERNAME=huginn \ -e DATABASE_USERNAME=huginn \
-e DATABASE_PASSWORD=somethingsecret \ -e DATABASE_PASSWORD=somethingsecret \
huginn/huginn-single-process /scripts/init bin/threaded.rb huginn/huginn-single-process /scripts/init bin/threaded.rb
or alternatively:
docker run --rm --name huginn_threaded \
--link huginn_mysql:mysql \
-e DATABASE_NAME=huginn \
-e DATABASE_USERNAME=huginn \
-e DATABASE_PASSWORD=somethingsecret \
-e WORKER_CMD='bin/threaded.rb' \
huginn/huginn-single-process
## Environment Variables ## Environment Variables
Other Huginn [12factored](https://12factor.net/) environment variables of note are generated and put into the .env file as per Huginn documentation. All variables of the [.env.example](https://github.com/huginn/huginn/blob/master/.env.example) can be used to override the defaults which a read from the current `.env.example`. Other Huginn [12factored](https://12factor.net/) environment variables of note are generated and put into the .env file as per Huginn documentation. All variables of the [.env.example](https://github.com/huginn/huginn/blob/master/.env.example) can be used to override the defaults which a read from the current `.env.example`.
@ -87,12 +97,10 @@ In newer versions of Docker you are able to pass your own .env file in to the co
You don't need to do this on your own, but if you really want run this command in the Huginn root directory: You don't need to do this on your own, but if you really want run this command in the Huginn root directory:
docker build --rm=true --tag={yourname}/huginn -f docker/single-process/Dockerfile . bin/docker_wrapper build --rm=true --tag={yourname}/huginn -f docker/single-process/Dockerfile .
## Source ## Source
The source is [available on GitHub](https://github.com/huginn/huginn/docker/single-process/). The source is [available on GitHub](https://github.com/huginn/huginn/tree/master/docker/single-process).
Please feel free to submit pull requests and/or fork at your leisure. Please feel free to submit pull requests and/or fork at your leisure.

View file

@ -1,44 +1,30 @@
#!/bin/bash #!/bin/bash
set -e set -e
export LC_ALL=en_US.UTF-8
cd /app cd /app
# Do we have a Rails secret yet? if [[ -z "$1" && -n "$WORKER_CMD" ]]; then
# If not, generate one, but persist it for the container's lifetime. set -- $WORKER_CMD
if [ -z "$APP_SECRET_TOKEN" ] && grep -q ^APP_SECRET_TOKEN=REPLACE_ME_NOW .env.example; then
echo 'Generating random APP_SECRET_TOKEN.'
secret=$(dd if=/dev/urandom bs=36 count=1 | openssl base64)
sed -i.orig "s:REPLACE_ME_NOW:$secret:" .env.example
fi fi
/scripts/setup_env source /scripts/setup_env
source /app/.env
# use default port number if it is still not set if [[ -z "${DO_NOT_CREATE_DATABASE}" && -z "$1" ]]; then
case "${DATABASE_ADAPTER}" in bundle exec rake db:create RAILS_ENV=${RAILS_ENV}
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 -E bundle install --without test development --path vendor/bundle
if [[ -z "${DO_NOT_CREATE_DATABASE}" && -z $1 ]]; then
sudo -u huginn -H -E bundle exec rake db:create RAILS_ENV=${RAILS_ENV}
fi fi
if [ -z $1 ]; then if [ -z "$1" ]; then
sudo -u huginn -H -E bundle exec rake db:migrate RAILS_ENV=${RAILS_ENV} bundle exec rake db:migrate RAILS_ENV=${RAILS_ENV}
fi fi
if [[ -z "${DO_NOT_SEED}" && -z $1 ]]; then if [[ -z "${DO_NOT_SEED}" && -z "$1" ]]; then
sudo -u huginn -H -E bundle exec rake db:seed RAILS_ENV=${RAILS_ENV} set +e
bundle exec rake db:seed RAILS_ENV=${RAILS_ENV}
set -e
fi fi
if [ -z $1 ]; then if [ -z "$1" ]; then
exec sudo -u huginn -H -E bundle exec unicorn -c config/unicorn.rb exec bundle exec unicorn -c config/unicorn.rb
else else
exec sudo -u huginn -H -E bundle exec rails runner "$@" RAILS_ENV=${RAILS_ENV} exec bundle exec rails runner "$@" RAILS_ENV=${RAILS_ENV}
fi fi

View file

@ -3,6 +3,8 @@ FROM huginn/huginn-single-process
ENV PHANTOM_VERSION "phantomjs-2.1.1" ENV PHANTOM_VERSION "phantomjs-2.1.1"
ENV PHANTOM_JS "${PHANTOM_VERSION}-linux-x86_64" ENV PHANTOM_JS "${PHANTOM_VERSION}-linux-x86_64"
USER 0
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install \ apt-get -y install \
build-essential \ build-essential \
@ -13,17 +15,14 @@ RUN apt-get update && \
libfreetype6-dev \ libfreetype6-dev \
libfontconfig1 \ libfontconfig1 \
libfontconfig1-dev curl && \ libfontconfig1-dev curl && \
apt-get -y clean && \
curl -Ls https://bitbucket.org/ariya/phantomjs/downloads/${PHANTOM_JS}.tar.bz2 \ curl -Ls https://bitbucket.org/ariya/phantomjs/downloads/${PHANTOM_JS}.tar.bz2 \
| tar jxvf - --strip-components=2 -C /usr/local/bin/ ${PHANTOM_JS}/bin/phantomjs | tar jxvf - --strip-components=2 -C /usr/local/bin/ ${PHANTOM_JS}/bin/phantomjs
ENV RAILS_ENV test RUN LC_ALL=en_US.UTF-8 ON_HEROKU=true bundle install --with test development --path vendor/bundle -j 4
RUN chown -R huginn:huginn /app && \
sudo -u huginn -H LC_ALL=en_US.UTF-8 ON_HEROKU=true bundle install --with test development --path vendor/bundle -j 4
ADD "docker/scripts/setup_env" "/scripts/" COPY docker/test/scripts/test_env /scripts/
ADD "docker/test/scripts/" "/scripts/"
USER huginn
WORKDIR /app
ENTRYPOINT ["/scripts/test_env"] ENTRYPOINT ["/scripts/test_env"]
CMD ["rake spec"] CMD ["rake spec"]
USER 1001

View file

@ -3,7 +3,7 @@ Docker image for Huginn testing
This image allows the [Huginn](https://github.com/huginn/huginn) test suite to be run in a container, against multiple databases. This image allows the [Huginn](https://github.com/huginn/huginn) test suite to be run in a container, against multiple databases.
It was inspired by the [official docker container for huginn](https://registry.hub.docker.com/u/cantino/huginn) It was inspired by the [official docker container for huginn](https://hub.docker.com/r/huginn/huginn)
In Development Mode, the source code of the current project directory is mounted as a volume overlaying the packaged `/app` directory. In Development Mode, the source code of the current project directory is mounted as a volume overlaying the packaged `/app` directory.

View file

@ -5,6 +5,8 @@ set -e
source /app/.env source /app/.env
export RAILS_ENV=test export RAILS_ENV=test
unset no_proxy
bundle install --with test development --path vendor/bundle -j 4 bundle install --with test development --path vendor/bundle -j 4
bundle exec rake db:create db:migrate bundle exec rake db:create db:migrate
bundle exec "$@" bundle exec "$@"