From 472ae4c90f33cdbb4967a39338fa054cee29d72c Mon Sep 17 00:00:00 2001 From: Pascal Date: Thu, 25 Feb 2021 00:54:35 -0500 Subject: [PATCH] [add] added docker --- Dockerfile | 69 ++++++++++++++++++++ docker-compose.yml | 32 ++++++++++ docker/files/entrypoint.sh | 125 +++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100755 docker/files/entrypoint.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..96ad80b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,69 @@ +ARG RUBY_VERSION=2.7.2 + +## BUILD ENV +FROM ruby:${RUBY_VERSION}-alpine AS build_env +ARG BUILD_PACKAGES="build-base curl-dev git" +ARG DEV_PACKAGES="sqlite-dev" +ARG RUBY_PACKAGES="tzdata" +ARG RAILS_ROOT=/app +ENV RAILS_ENV=production +ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle" +WORKDIR $RAILS_ROOT + +# install packages +RUN apk update \ + && apk upgrade \ + && apk add --update --no-cache $BUILD_PACKAGES $DEV_PACKAGES $RUBY_PACKAGES + +# copy app and cleanup dev environment in case this is not a clean git clone +COPY . . +RUN rm -rf .bundle vendor .vendor tmp/* db/*.sqlite3 log/* spec + +# install gems +RUN gem install bundler:2.2.9 \ + && bundle config --global frozen 1 \ + && bundle config --local path 'vendor/bundle' \ + && bundle config set without 'development:test:assets' \ + && bundle install -j4 --retry 3 \ + # Remove unneeded files (cached *.gem, *.o, *.c) + && rm -rf vendor/bundle/ruby/*/cache/*.gem \ + && find vendor/bundle/ruby/*/gems/ -name "*.c" -delete \ + && find vendor/bundle/ruby/*/gems/ -name "*.o" -delete + +# remove folders not needed in resulting image +RUN rm -rf tmp/cache app/assets vendor/assets spec docker + +## DEPLOY ENV +FROM ruby:${RUBY_VERSION}-alpine +ARG PACKAGES="tzdata sqlite-libs" +ARG RAILS_ROOT=/app +ENV RAILS_ENV=production +ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle" +ARG USER_UID=12001 +ARG USER_GID=12001 +ARG GROUP_NAME=ryndns +ARG USER_NAME=ryndns +WORKDIR $RAILS_ROOT + +# make user +RUN set -eux; \ + addgroup -g $USER_UID $GROUP_NAME; \ + adduser -u $USER_UID -G $GROUP_NAME -s /sbin/nologin -D $USER_NAME; + +# install packages +RUN apk update \ + && apk upgrade \ + && apk add --update --no-cache $PACKAGES + +# get app from build env and add entrypoint +COPY --from=build_env $RAILS_ROOT $RAILS_ROOT +COPY ./docker/files/entrypoint.sh / + +# create persistent folder and change permission of app +RUN mkdir -p $RAILS_ROOT/data \ + && chown -R $USER_NAME:$GROUP_NAME $RAILS_ROOT + +USER $USER_NAME + +EXPOSE 3000 +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f3e5810 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.7' + +services: + ryndns: + build: + context: . + args: + USER_UID: ${UID_PROXY:-12001} + USER_GID: ${UID_PROXY:-12001} + environment: + # set to run app in subdirectory + RAILS_RELATIVE_URL_ROOT: /rynDNS + # set custom api key prefix + #API_KEY_PREFIX: zW3If4s5 + # set custom header name for api key + #API_KEY_HEADER: X-API-Key + # set to reset the admin account + #RAILS_RESET_ADMIN: 1 + # set app to run as demo + #RAILS_API_DEMO: 1 + # set cycle to reset demo data + #RAILS_DEMO_RESET: 300 + restart: always + image: ryndns + container_name: ryndns + ports: + - "3000:3000" + volumes: + - ryndns:/app/data + +volumes: + ryndns: \ No newline at end of file diff --git a/docker/files/entrypoint.sh b/docker/files/entrypoint.sh new file mode 100755 index 0000000..afb9873 --- /dev/null +++ b/docker/files/entrypoint.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +############################## +# configuration + +prefix_file="${API_PREFIX_FILE:-/app/data/api_prefix}" +db_file="${RAILS_DB_PATH:-/app/data/rynDNS.sqlite3}" +default_admin_file="${API_DEFAULT_KEY_FILE:-/app/data/api_default_admin}" +rails_bin="${RAILS_BINARY:-/app/bin/rails}" +demo_cycle="${RAILS_DEMO_RESET:-300s}" +demo_prefix="zW3If4s5" +seed_default_key_text="Created default admin with api_key" # for grep'ing the default admin key + +# end configuration +############################## + +function log() +{ + local time=$(date +%F_%T) + local prefix="LOG" + case $1 in + ERR | ERROR) + prefix="ERR" + shift + ;; + WAR | WARNING) + prefix="WAR" + shift + ;; + INF | INFO) + prefix="INF" + shift + ;; + esac + local func=$1; shift + # remove any \n + #local text=$(echo "$@"| tr '\n' '#' | sed 's|#|\\n |g') + case "$logfile" in + "") + echo "[$time]:[$prefix]:[$0][$func]: $@" 2>&1 + ;; + *) + echo "[$time]:[$prefix]:[$0][$func]: $@" >> $logfile + ;; + esac +} + +function random_sting() +{ + echo -n "$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w "${1:-32}" | head -n 1)" +} + +function get_prefix_file() +{ + if [ -f "$prefix_file" ]; then + echo -n "$(head -1 $prefix_file)" + else + new_prefix=$(random_sting 8) + log get_prefix_file no prefix file, generating new one + echo -n "$new_prefix" > "$prefix_file" + echo -n "$new_prefix" + fi +} + +function set_api_prefix() +{ + if [ -z "$RAILS_API_KEY_PREFIX" ]; then + log set_api_prefix setting prefix from file + RAILS_API_KEY_PREFIX=$(get_prefix_file | tail -1) + export RAILS_API_KEY_PREFIX + else + log set_api_prefix saving prefix from ENV to file + echo -n "$RAILS_API_KEY_PREFIX" > "$prefix_file" + fi +} + +function demo_cleaner() +{ + while true; do + log demo_cleaner cleaning up; + db_setup + # starting sleep in subshell to be able to quickly terminate + sleep $demo_cycle & + wait + done +} + +function demo() +{ + if [ ! -z "$RAILS_API_DEMO" ]; then + log demo "setting prefix to $demo_prefix" + RAILS_API_KEY_PREFIX="$demo_prefix" + export RAILS_API_KEY_PREFIX + log demo "setting up demo cleaner, resetting every $demo_cycle" + demo_cleaner & + fi +} + +function db_setup() +{ + if [ ! -f $db_file ]; then + log db_setup running first time migrations + echo "$($rails_bin db:migrate)" + fi + log db_setup seeding database + seed_log="$($rails_bin db:seed)" + echo "$seed_log" + # save default login to file + default_admin=$(echo "$seed_log" | grep "$seed_default_key_text") + [ "${#default_admin}" -gt 8 ] && echo -n "$default_admin" > $default_admin_file + log db_setup "see \`docker exec \$CONTAINER cat $default_admin_file\` for initial admin api_key" +} + +function main() +{ + set_api_prefix + log main prefix: $RAILS_API_KEY_PREFIX + db_setup + [ "$(id -u)" -eq 0 ] && log WARN main running server as root + demo + log main starting server + exec $rails_bin s +} + +main "$@" \ No newline at end of file