Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerfile rebuild #1881

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 41 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
FROM ruby:3.2-alpine3.18 AS build

RUN apk add --no-cache tzdata alpine-sdk postgresql-dev nodejs yarn xz libarchive mesa-gl glfw
RUN gem install foreman
RUN addgroup -S -g 1000 manyfold && adduser -S -H -G manyfold -u 1000 manyfold

RUN apk add --no-cache \
coreutils \
tzdata \
alpine-sdk \
postgresql-dev \
nodejs \
yarn \
xz \
libarchive \
mesa-gl \
glfw \
bash \
su-exec \
wget

# (bundler needs this for running as an arbitrary user)
ENV HOME /home/manyfold
RUN [ ! -d "$HOME" ]; \
mkdir -p "$HOME"; \
chown manyfold:manyfold "$HOME"; \
chmod 1777 "$HOME"

ARG APP_VERSION
ARG GIT_SHA
Expand All @@ -13,25 +34,31 @@ ENV NODE_ENV=production
ENV RAILS_SERVE_STATIC_FILES=true
ENV APP_VERSION=${APP_VERSION}
ENV GIT_SHA=${GIT_SHA}

WORKDIR /usr/src/app

COPY package.json .
COPY yarn.lock .
COPY . .
RUN yarn config set network-timeout 600000 -g
RUN yarn install --prod

RUN gem install bundler -v 2.4.13
RUN su-exec manyfold gem install foreman
RUN su-exec manyfold gem install bundler -v 2.4.13
RUN bundle config set --local deployment 'true'
RUN bundle config set --local without 'development test'
COPY Gemfile* ./
RUN bundle install
RUN chmod -R ugo=rwX Gemfile.lock "$GEM_HOME";
# this requires coreutils because "chmod +X" in busybox will remove +x on files (and coreutils leaves files alone with +X)
RUN rm -rf ~manyfold/.bundle

COPY . .
RUN \
DATABASE_URL="nulldb://user:pass@localhost/db" \
SECRET_KEY_BASE="placeholder" \
bundle exec rake assets:precompile

RUN chown -R manyfold:manyfold ./ \
chmod -R ugo=rwX config db; \
find log tmp -type d -exec chmod 1777 '{}' +

RUN echo '# the following entries only exist to force `bundle install` to pre-install all database adapter dependencies -- they can be safely removed/ignored' > ./config/database.yml; \
for adapter in mysql2 postgresql sqlserver sqlite3; do \
echo "$adapter:" >> ./config/database.yml; \
echo " adapter: $adapter" >> ./config/database.yml; \
done; \
su-exec manyfold bundle install --jobs "$(nproc)"; \
rm ./config/database.yml;

EXPOSE 3214
ENTRYPOINT ["bin/docker-entrypoint.sh"]
Expand Down
143 changes: 133 additions & 10 deletions bin/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,137 @@
#!/bin/sh
set -e
if [ -f tmp/pids/server.pid ]; then
rm tmp/pids/server.pid
#!/usr/bin/env bash
set -Eeo pipefail
# TODO add "-u"

# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}

isLikelyManyfold=
case "$1" in
rails | rake | foreman ) isLikelyManyfold=1 ;;
esac

_fix_permissions() {
# https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-8-File-system-permissions
local dirs=( config log tmp ) args=()
if [ "$(id -u)" = '0' ]; then
args+=( '(' '!' -user manyfold -exec chown manyfold:manyfold '{}' + ')' )
fi
# directories 755, files 644:
args+=( '(' -type d '!' -perm 755 -exec sh -c 'chmod 755 "$@" 2>/dev/null || :' -- '{}' + ')' )
args+=( '(' -type f '!' -perm 644 -exec sh -c 'chmod 644 "$@" 2>/dev/null || :' -- '{}' + ')' )
if [ ${#args[@]} -gt 0 ]; then
find "${dirs[@]}" "${args[@]}"
fi
}


# allow the container to be started with `--user`
if [ -n "$isLikelyManyfold" ] && [ "$(id -u)" = '0' ]; then
_fix_permissions
exec su-exec manyfold "$BASH_SOURCE" "$@"
fi

echo "Preparing database..."
bundle exec rails db:prepare:with_data
if [ -n "$isLikelyManyfold" ]; then
_fix_permissions
if [ ! -f './config/database.yml' ]; then
file_env 'MANYFOLD_DB_POSTGRES'
if [ "$POSTGRES_PORT_5432_TCP" ] && [ -z "$MANYFOLD_DB_POSTGRES" ]; then
export MANYFOLD_DB_POSTGRES='postgres'
fi

if [ "$MANYFOLD_DB_POSTGRES" ]; then
adapter='postgresql'
host="$MANYFOLD_DB_POSTGRES"
file_env 'MANYFOLD_DB_PORT' '5432'
file_env 'MANYFOLD_DB_USERNAME' "${POSTGRES_ENV_POSTGRES_USER:-postgres}"
file_env 'MANYFOLD_DB_PASSWORD' "${POSTGRES_ENV_POSTGRES_PASSWORD}"
file_env 'MANYFOLD_DB_DATABASE' "${POSTGRES_ENV_POSTGRES_DB:-${MANYFOLD_DB_USERNAME:-}}"
file_env 'MANYFOLD_DB_ENCODING' 'utf8'
else
echo >&2
echo >&2 'warning: missing MANYFOLD_DB_POSTGRES environment variables'
echo >&2
echo >&2 '*** Using sqlite3 as fallback. ***'
echo >&2

adapter='sqlite3'
host='localhost'
file_env 'MANYFOLD_DB_PORT' ''
file_env 'MANYFOLD_DB_USERNAME' 'manyfold'
file_env 'MANYFOLD_DB_PASSWORD' ''
file_env 'MANYFOLD_DB_DATABASE' 'sqlite/manyfold.db'
file_env 'MANYFOLD_DB_ENCODING' 'utf8'
mkdir -p "$(dirname "$MANYFOLD_DB_DATABASE")"
if [ "$(id -u)" = '0' ]; then
find "$(dirname "$MANYFOLD_DB_DATABASE")" \! -user manyfold -exec chown manyfold '{}' +
fi
fi

echo "Clearing up old jobs..."
bundle exec rake jobs:clear
MANYFOLD_DB_ADAPTER="$adapter"
MANYFOLD_DB_HOST="$host"
echo "$RAILS_ENV:" > config/database.yml
for var in \
adapter \
host \
port \
username \
password \
database \
encoding \
; do
env="MANYFOLD_DB_${var^^}"
val="${!env}"
[ -n "$val" ] || continue
echo " $var: \"$val\"" >> config/database.yml
done
echo " pool: <%= ENV.fetch(\"RAILS_MAX_THREADS\", 16) %>" >> config/database.yml
fi

# install additional gems for Gemfile.local and plugins
bundle check || bundle install

if [ ! -s config/secrets.yml ]; then
file_env 'MANYFOLD_SECRET_KEY_BASE'
if [ -n "$MANYFOLD_SECRET_KEY_BASE" ]; then
cat > 'config/secrets.yml' <<-YML
$RAILS_ENV:
secret_key_base: "$MANYFOLD_SECRET_KEY_BASE"
YML
elif [ ! -f config/initializers/secret_token.rb ]; then
bundle exec rake generate_secret_token
fi
fi
if [ "$1" != 'rake' -a -z "$MANYFOLD_NO_DB_MIGRATE" ]; then
bundle exec rake db:migrate
fi

if [ "$1" != 'rake' -a -n "$MANYFOLD_PLUGINS_MIGRATE" ]; then
bundle exec rake manyfold:plugins:migrate
fi

bundle exec rake assets:precompile

# remove PID file to enable restarting the container
rm -f tmp/pids/server.pid
fi

echo "Launching application..."
exec "$@"
exec "$@"
10 changes: 7 additions & 3 deletions docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ services:
ports:
- 3214:3214
volumes:
- /path/to/your/libraries:/libraries
- /path/to/library:/libraries
environment:
DATABASE_URL: postgresql://manyfold:password@db/manyfold?pool=5
SECRET_KEY_BASE: a_nice_long_random_string
REDIS_URL: redis://redis:6379/1
MANYFOLD_DB_POSTGRES: db
MANYFOLD_DB_USERNAME: manyfold
MANYFOLD_DB_PASSWORD: password
MANYFOLD_SECRET_KEY_BASE: supersecretkey
PUID: 1000
PGID: 1000
# RAILS_RELATIVE_URL_ROOT: /manyfold Sets the root of the app to /manyfold useful for reverse proxies with nginx
depends_on:
- db
Expand Down
Loading