diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..e235b236 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +docker-compose.* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..86a6d4d1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +FROM ruby:2.3 + +MAINTAINER TheAssassin + +# required for compiling assets +RUN apt-get update && \ + apt-get install -y nodejs nodejs-legacy mariadb-client + +# used to run the container without root permissions +RUN adduser --home /osem/ --system --group --disabled-login --disabled-password osem + +# required to detect when the database is up and running in init.sh +RUN cd /usr/bin && \ + wget https://github.com/jwilder/dockerize/releases/download/v0.3.0/dockerize-linux-amd64-v0.3.0.tar.gz -O dockerize.tar.gz && \ + echo "36e8319cdf9d2b07340f456ec61cfa0f495ec6c130b02ad9c116fd55a5c43fa1 dockerize.tar.gz" | sha256sum -c && \ + tar -xf dockerize.tar.gz && \ + rm dockerize.tar.gz + +# explicitly add Gemfile and install dependencies using bundler to make use of +# Docker's caching +WORKDIR /osem/ +RUN gem install puma +COPY Gemfile /osem/ +COPY Gemfile.lock /osem/ +RUN bundle install --without test development + +# add OSEM files and prepare them for use inside a Docker container +COPY . /osem/ +RUN chown osem.osem /osem/ -R && \ + mv /osem/config/database.yml.docker /osem/config/database.yml + +# data directory is used to cache the secret key in a file +ENV DATA_DIR /data +RUN install -d -m 0700 -o osem $DATA_DIR +VOLUME ["$DATA_DIR"] + +USER osem +EXPOSE 9292 + +COPY docker/init.sh /init.sh + +# a user could override this if they wanted to serve the static files directly +# from a webserver +ENV RAILS_SERVE_STATIC_FILES 1 + +CMD ["bash", "/init.sh"] diff --git a/config/database.yml.docker b/config/database.yml.docker new file mode 100644 index 00000000..60ef8947 --- /dev/null +++ b/config/database.yml.docker @@ -0,0 +1,7 @@ +production: + adapter: mysql2 + host: <%= ENV['DATABASE_HOST'] %> + port: <%= ENV['DATABASE_PORT'] %> + username: <%= ENV['MYSQL_USER'] %> + password: <%= ENV['MYSQL_PASSWORD'] %> + database: <%= ENV['MYSQL_DATABASE'] %> diff --git a/docker-compose.env.example b/docker-compose.env.example new file mode 100644 index 00000000..911b8062 --- /dev/null +++ b/docker-compose.env.example @@ -0,0 +1,38 @@ +## database related variables ## + +# variables prefixed with MYSQL_ are used by both database and web containers +# variables prefixed with DATABASE_ are used exlusively by the web container + +MYSQL_DATABASE=osem +MYSQL_USER=osem +MYSQL_PASSWORD=changemeimmediately +MYSQL_ROOT_PASSWORD=changemeevenmoreimmediately + +# the following settings should not be modified unless the database service +# is renamed in docker-compose.yml or you plan to use an external database +DATABASE_HOST=database +DATABASE_PORT=3306 + + +## OSEM options ## +# you can configure any option described in this document here instead of +# having to create a .env file: +# https://github.com/openSUSE/osem/blob/master/dotenv.example + +OSEM_NAME=Dockerized OSEM +OSEM_HOSTNAME=http://localhost:9292 +OSEM_ERRBIT_HOST=localhost +SECRET_KEY_BASE=changemechangemechangeme + +# these settings work for the MailHog server that is enabled by default in +# docker-compose.yml +# if you do not plan to use MailHog (you most likely don't want to), you need +# to change these settings to use an external working mailserver, otherwise +# your users are going to see the HTTP status 500 page +# you should comment out or remove the mailhog service from docker-compose.yml, +# too +OSEM_EMAIL_ADDRESS=osem@mailhog +OSEM_SMTP_ADDRESS=mailhog +OSEM_SMTP_PORT=1025 +OSEM_SMTP_USERNAME=mailhog +OSEM_SMTP_PASSWORD=mailhog diff --git a/docker-compose.yml.example b/docker-compose.yml.example new file mode 100644 index 00000000..0959523c --- /dev/null +++ b/docker-compose.yml.example @@ -0,0 +1,29 @@ +version: "2" + +services: + database: + image: mariadb:10.1 + env_file: docker-compose.env + volumes: + - database:/var/lib/mysql + + mailhog: + image: mailhog/mailhog:latest + ports: + - "127.0.0.1:8025:8025" + + web: + build: . + env_file: docker-compose.env + depends_on: + - database + - mailhog + ports: + - "127.0.0.1:9292:9292" + volumes: + - "web:/data" + +# these named volumes are used to persist data +volumes: + database: + web: diff --git a/docker/init.sh b/docker/init.sh new file mode 100644 index 00000000..36601e6c --- /dev/null +++ b/docker/init.sh @@ -0,0 +1,45 @@ +#! /bin/bash + +set -e + +# data directory is required for caching the secret key in a file +if [ "$DATA_DIR" == "" ]; then + echo -n "Error: DATA_DIR environment variable not set!" + echo "Are you sure you are running this script in a Docker container?" + exit 1 +fi + +SECRET_KEY_FILE="$DATA_DIR/secret_key" + +if [ ! -f "$SECRET_KEY_FILE" ]; then + install -m 0600 /dev/null "$SECRET_KEY_FILE" + SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 100 | head -n 1) + echo "$key" > "$SECRET_KEY_FILE" + chmod -w "$SECRET_KEY_FILE" +else + SECRET_KEY=$(cat "$SECRET_KEY_FILE") +fi + +export SECRET_KEY +export RAILS_ENV=production + +install -m 0600 /dev/null .my.cnf +cat > .my.cnf <>> Initializing database..." + dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:schema:load +fi + +echo ">>> Upgrading database..." +dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s bundle exec rake db:migrate + +echo ">>> Precompiling assets..." +bundle exec rake assets:precompile + +echo ">>> Starting application server..." +exec puma -e production