Simplify docker image, allow to switch between all-in-one and single process easily

pull/7120/head
Cyril Rohr 6 years ago
parent 5a3760e60e
commit 65ab9fe8cb
  1. 52
      Dockerfile
  2. 3
      docker/console
  3. 122
      docker/entrypoint.sh
  4. 212
      docker/nginx.conf.erb
  5. 5
      docker/precompile-assets.sh
  6. 2
      docker/proxy
  7. 2
      docker/proxy.conf.erb
  8. 115
      docker/supervisord
  9. 63
      docker/supervisord.conf
  10. 161
      docker/wait-for-it.sh
  11. 1
      docker/web

@ -1,27 +1,27 @@
FROM ruby:2.6-stretch
MAINTAINER operations@openproject.com
ENV NODE_VERSION="10.15.0"
ENV BUNDLER_VERSION="2.0.1"
ENV NODE_VERSION "10.15.0"
ENV BUNDLER_VERSION "2.0.1"
ENV APP_USER app
ENV APP_PATH /usr/src/app
ENV APP_DATA /var/db/openproject
ENV ATTACHMENTS_STORAGE_PATH /var/db/openproject/files
ENV DATABASE_URL=postgres://openproject:openproject@127.0.0.1/openproject
ENV RAILS_ENV=production
ENV HEROKU=true
ENV RAILS_CACHE_STORE=memcache
ENV OPENPROJECT_INSTALLATION__TYPE=docker
ENV APP_PATH /app
ENV APP_DATA_PATH /var/openproject/assets
ENV PGDATA /var/openproject/pgdata
ENV DATABASE_URL postgres://openproject:openproject@127.0.0.1/openproject
ENV RAILS_ENV production
ENV HEROKU true
ENV RAILS_CACHE_STORE memcache
ENV ATTACHMENTS_STORAGE_PATH $APP_DATA_PATH/files
ENV OPENPROJECT_INSTALLATION__TYPE docker
ENV NEW_RELIC_AGENT_ENABLED false
# Set a default key base, ensure to provide a secure value in production environments!
ENV SECRET_KEY_BASE=OVERWRITE_ME
ENV SECRET_KEY_BASE OVERWRITE_ME
# install node + npm
RUN curl https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz | tar xzf - -C /usr/local --strip-components=1
USER root
RUN apt-get update -qq && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
postgresql-client \
@ -39,15 +39,16 @@ RUN apt-get update -qq && \
# Set up pg defaults
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.6/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.6/main/postgresql.conf
RUN rm -rf /var/lib/postgresql/9.6/main && mkdir -p /var/lib/postgresql/9.6/main && chown -R postgres:postgres /var/lib/postgresql/9.6
RUN echo "data_directory='$PGDATA'" >> /etc/postgresql/9.6/main/postgresql.conf
RUN rm -rf "$PGDATA" && mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA"
RUN a2enmod proxy proxy_http && rm -f /etc/apache2/sites-enabled/000-default.conf
# using /home/app since npm cache and other stuff will be put there when running npm install
# we don't want to pollute any locally-mounted directory
RUN useradd -d /home/$APP_USER -m $APP_USER
RUN mkdir -p $APP_PATH $APP_DATA
RUN mkdir -p /var/db/openproject/{files,git,svn}
RUN chown -R $APP_USER:$APP_USER $APP_DATA
RUN mkdir -p $APP_PATH $APP_DATA_PATH
RUN mkdir -p $APP_DATA_PATH/{files,git,svn}
RUN chown -R $APP_USER:$APP_USER $APP_DATA_PATH
RUN gem install bundler --version "${bundler_version}" --no-document
@ -63,17 +64,11 @@ RUN bundle install --deployment --with="docker opf_plugins" --without="test deve
# Finally, copy over the whole thing
COPY . $APP_PATH
RUN cp docker/Procfile .
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN sed -i "s|Rails.groups(:opf_plugins)|Rails.groups(:opf_plugins, :docker)|" config/application.rb
# Ensure we can write in /tmp/op_uploaded_files (cf. #29112)
RUN mkdir -p /tmp/op_uploaded_files/
RUN chown -R $APP_USER:$APP_USER /tmp/op_uploaded_files/
# Allow uploading avatars w/ postgres
RUN chown -R $APP_USER:$APP_USER $APP_DATA
RUN mkdir -p /tmp/op_uploaded_files/ && chown -R $APP_USER:$APP_USER /tmp/op_uploaded_files/
# Re-use packager database.yml
COPY packaging/conf/database.yml ./config/database.yml
@ -82,13 +77,10 @@ COPY packaging/conf/database.yml ./config/database.yml
# Then, npm install node modules
RUN bash docker/precompile-assets.sh
# Remove node_modules and entire frontend
RUN rm -rf $APP_PATH/node_modules/ $APP_PATH/frontend/node_modules/
# ports
EXPOSE 80 5432
# volumes to export
VOLUME ["/var/lib/postgresql/9.6/main", "$APP_DATA"]
CMD ["./docker/web"]
VOLUME ["$PGDATA", "$APP_DATA_PATH"]
ENTRYPOINT ["./docker/entrypoint.sh"]
CMD ["./docker/supervisord"]

@ -0,0 +1,3 @@
#!/bin/bash
set -e
exec bundle exec rails c

@ -3,121 +3,19 @@
set -e
set -o pipefail
PGDATA=${PGDATA:=/var/lib/postgresql/9.6/main}
PGUSER=${PGUSER:=postgres}
PGPASSWORD=${PGPASSWORD:=postgres}
PG_STARTUP_WAIT_TIME=${PG_STARTUP_WAIT_TIME:=10}
SUPERVISORD_LOG_LEVEL=${SUPERVISORD_LOG_LEVEL:=info}
PGBIN="/usr/lib/postgresql/9.6/bin"
if [ ! -z "$ATTACHMENTS_STORAGE_PATH" ]; then
mkdir -p "$ATTACHMENTS_STORAGE_PATH"
chown -R app:app "$ATTACHMENTS_STORAGE_PATH"
fi
if [ "$(id -u)" = '0' ]; then
echo "-----> Ensure $APP_PATH is owned by $APP_USER"
mkdir -p "$APP_PATH/log" "$APP_PATH/tmp" "$APP_PATH/files"
chown $APP_USER:$APP_USER "$APP_PATH"
chown -R $APP_USER:$APP_USER "$APP_PATH/log" "$APP_PATH/tmp" "$APP_PATH/files" "$APP_PATH/public"
fi
dbhost=$(ruby -ruri -e 'puts URI(ENV.fetch("DATABASE_URL")).host')
pwfile=$(mktemp)
echo "$PGPASSWORD" > $pwfile
chown postgres $pwfile
PLUGIN_GEMFILE_TMP=$(mktemp)
PLUGIN_GEMFILE=/usr/src/app/Gemfile.local
if [ "$PLUGIN_GEMFILE_URL" != "" ]; then
echo "Fetching custom gemfile from ${PLUGIN_GEMFILE_URL}..."
curl -L -o "$PLUGIN_GEMFILE_TMP" "$PLUGIN_GEMFILE_URL"
# set custom plugin gemfile if file is readable and non-empty
if [ -s "$PLUGIN_GEMFILE_TMP" ]; then
mv "$PLUGIN_GEMFILE_TMP" "$PLUGIN_GEMFILE"
chown $APP_USER:$APP_USER "$PLUGIN_GEMFILE"
fi
fi
indent() {
sed -u 's/^/ /'
}
install_plugins() {
pushd /usr/src/app
if [ -s "$PLUGIN_GEMFILE" ]; then
echo "Installing plugins..."
bundle install
echo "Installing frontend dependencies..."
pushd /usr/src/app/frontend
if [ "$(id -u)" = '0' ]; then
su - $APP_USER -c "cd $APP_PATH/frontend && npm install"
else
npm install
fi
popd
echo "Precompiling new assets..."
bundle exec rake assets:precompile
echo "Plugins installed"
if [ ! -z "$ATTACHMENTS_STORAGE_PATH" ]; then
mkdir -p "$ATTACHMENTS_STORAGE_PATH"
chown -R "$APP_USER:$APP_USER" "$ATTACHMENTS_STORAGE_PATH"
fi
popd
}
migrate() {
wait_for_postgres
pushd /usr/src/app
/etc/init.d/memcached start
bundle exec rake db:migrate db:seed db:structure:dump
/etc/init.d/memcached stop
chown app:app db/structure.sql
popd
}
wait_for_postgres() {
retries=${PG_STARTUP_WAIT_TIME}
echo "Trying to contact PostgreSQL server instance or waiting for it to come online."
until su postgres -c "$PGBIN/psql $DATABASE_URL -c 'select 1;' > /dev/null 2>&1" || [ $retries -eq 0 ]; do
echo "Waiting for postgres server, $((retries--)) remaining attempts..."
sleep 3
done
}
if [ "$dbhost" = "127.0.0.1" ]; then
# initialize cluster if it does not exist yet
if [ -f "$PGDATA/PG_VERSION" ]; then
echo "-----> Database cluster already exists, not modifying."
/etc/init.d/postgresql start | indent
(install_plugins && migrate) | indent
/etc/init.d/postgresql stop | indent
mkdir -p "$APP_PATH/log" "$APP_PATH/tmp/pids" "$APP_PATH/files"
chown "$APP_USER:$APP_USER" "$APP_PATH"
chown -R "$APP_USER:$APP_USER" "$APP_PATH/log" "$APP_PATH/tmp" "$APP_PATH/files" "$APP_PATH/public"
if [ "$1" = "./docker/supervisord" ]; then
exec "$@"
else
echo "-----> Database cluster not found. Creating a new one in $PGDATA..."
chown -R postgres:postgres $PGDATA
su postgres -c "$PGBIN/initdb --pgdata=${PGDATA} --username=${PGUSER} --encoding=unicode --auth=trust --pwfile=$pwfile" | indent
su postgres -c "rm -f $pwfile"
/etc/init.d/postgresql start | indent
su postgres -c "$PGBIN/psql --command \"CREATE USER openproject WITH SUPERUSER PASSWORD 'openproject';\"" | indent
su postgres -c "$PGBIN/createdb -O openproject openproject" | indent
(install_plugins && migrate) | indent
/etc/init.d/postgresql stop | indent
exec $APP_PATH/docker/gosu $APP_USER "$BASH_SOURCE" "$@"
fi
else
echo "-----> You're using an external database. Not initializing a local database cluster."
migrate | indent
fi
echo "-----> Database setup finished."
echo " On first installation, the default admin credentials are login: admin, password: admin"
echo "-----> Launching supervisord..."
exec /usr/bin/supervisord -e ${SUPERVISORD_LOG_LEVEL}
exec "$@"

@ -1,212 +0,0 @@
##############################################################
# Phusion Passenger Standalone uses a template file to
# generate an Nginx configuration file. The original template
# file can be found by running the following command:
#
# ls $(passenger-config about resourcesdir)/templates/standalone/config.erb
#
# You can create a copy of this template file and customize it
# to your liking. Just make sure you tell Phusion Passenger Standalone
# to use your template file by passing the --nginx-config-template
# parameter.
#
# *** NOTE ***
# If you customize the template file, make sure you keep an eye
# on the original template file and merge any changes.
# New Phusion Passenger features may require changes to the template
# file.
##############################################################
master_process on;
worker_processes 1;
daemon on;
error_log '<%= @options[:log_file] %>' <% if @options[:log_level] >= LVL_DEBUG %>info<% end %>;
pid '<%= @options[:pid_file] %>';
<% if Process.euid == 0 %>
<% if @options[:user] %>
<%# Run workers as the given user. The master process will always run as root and will be able to bind to any port. %>
user <%= @options[:user] %> <%= default_group_for(@options[:user]) %>;
<% else %>
<%# Prevent running Nginx workers as nobody. %>
user <%= current_user %> <%= default_group_for(current_user) %>;
<% end %>
<% end %>
events {
worker_connections 1024;
}
http {
log_format debug '[$time_local] $msec "$request" $status conn=$connection sent=$bytes_sent body_sent=$body_bytes_sent';
include '<%= PhusionPassenger.resources_dir %>/mime.types';
<% if @options[:ruby] %>
passenger_ruby <%= @options[:ruby] %>;
<% else %>
passenger_ruby <%= PlatformInfo.ruby_command %>;
<% end %>
<% if @options[:nodejs] %>
passenger_nodejs <%= @options[:nodejs] %>;
<% end %>
<% if @options[:python] %>
passenger_python <%= @options[:python] %>;
<% end %>
passenger_root '<%= PhusionPassenger.install_spec %>';
passenger_abort_on_startup_error on;
passenger_ctl cleanup_pidfiles <%= serialize_strset("#{@working_dir}/temp_dir_toucher.pid") %>;
passenger_ctl integration_mode standalone;
passenger_ctl standalone_engine nginx;
passenger_user_switching off;
<%= nginx_option :passenger_log_level, :log_level %>
<%= nginx_option :passenger_max_pool_size, :max_pool_size %>
<%= nginx_option :passenger_min_instances, :min_instances %>
<%= nginx_option :passenger_pool_idle_time, :pool_idle_time %>
<%= nginx_option :passenger_max_preloader_idle_time, :max_preloader_idle_time %>
<%= nginx_option :passenger_turbocaching, :turbocaching %>
<% if @options[:user] %>
passenger_user <%= @options[:user] %>;
passenger_default_user <%= @options[:user] %>;
passenger_analytics_log_user <%= @options[:user] %>;
<% else %>
passenger_user <%= current_user %>;
passenger_default_user <%= current_user %>;
passenger_analytics_log_user <%= current_user %>;
<% end %>
<% if @options[:instance_registry_dir] %>passenger_instance_registry_dir '<%= @options[:instance_registry_dir] %>';<% end %>
<% if @options[:data_buffer_dir] %>passenger_data_buffer_dir '<%= @options[:data_buffer_dir] %>';<% end %>
<% if @options[:rolling_restarts] %>passenger_rolling_restarts on;<% end %>
<% if @options[:resist_deployment_errors] %>passenger_resist_deployment_errors on;<% end %>
<% if !@options[:load_shell_envvars] %>passenger_load_shell_envvars off;<% end %>
<% if !@options[:friendly_error_pages].nil? -%>
passenger_friendly_error_pages <%= boolean_config_value(@options[:friendly_error_pages]) %>;
<% end %>
<% if @options[:union_station_gateway_address] %>
union_station_gateway_address <%= @options[:union_station_gateway_address] %>;
<% end %>
<% if @options[:union_station_gateway_port] %>
union_station_gateway_port <%= @options[:union_station_gateway_port] %>;
<% end %>
<% if @options[:union_station_gateway_cert] %>
union_station_gateway_cert -;
<% end %>
<% @options[:ctls].each do |ctl| %>
passenger_ctl '<%= ctl.split("=", 2)[0] %>' '<%= ctl.split("=", 2)[1] %>';
<% end %>
default_type application/octet-stream;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
client_max_body_size 20m;
access_log off;
keepalive_timeout 60;
underscores_in_headers on;
gzip on;
gzip_comp_level 3;
gzip_min_length 150;
gzip_proxied any;
gzip_types text/plain text/css text/json text/javascript
application/javascript application/x-javascript application/json
application/rss+xml application/vnd.ms-fontobject application/x-font-ttf
application/xml font/opentype image/svg+xml text/xml;
<% if @app_finder.multi_mode? %>
# Default server entry for mass deployment mode.
server {
<% if @options[:ssl] %>
<% if @options[:ssl_port] %>
listen <%= nginx_listen_address %>;
listen <%= nginx_listen_address_with_ssl_port %> ssl;
<% else %>
listen <%= nginx_listen_address %> ssl;
<% end %>
<% else %>
listen <%= nginx_listen_address %>;
<% end %>
root '<%= PhusionPassenger.resources_dir %>/standalone_default_root';
}
<% end %>
<% for app in @apps %>
server {
<% if app[:ssl] %>
<% if app[:ssl_port] %>
listen <%= nginx_listen_address(app) %>;
listen <%= nginx_listen_address_with_ssl_port(app) %> ssl;
<% else %>
listen <%= nginx_listen_address(app) %> ssl;
<% end %>
<% else %>
listen <%= nginx_listen_address(app) %>;
<% end %>
server_name <%= app[:server_names].join(' ') %>;
<% if app[:static_files_dir] %>
root '<%= app[:static_files_dir] %>';
<% else %>
root '<%= app[:root] %>/public';
<% end %>
passenger_app_root '<%= app[:root] %>';
passenger_enabled on;
passenger_app_env <%= app[:environment] %>;
passenger_spawn_method <%= app[:spawn_method] %>;
<% if app[:app_type] %>passenger_app_type <%= app[:app_type] %>;<% end %>
<% if app[:startup_file] %>passenger_startup_file <%= app[:startup_file] %>;<% end %>
<% if app[:concurrency_model] && app[:concurrency_model] != DEFAULT_CONCURRENCY_MODEL %>passenger_concurrency_model <%= app[:concurrency_model] %>;<% end %>
<% if app[:thread_count] && app[:thread_count] != DEFAULT_APP_THREAD_COUNT %>passenger_thread_count <%= app[:thread_count] %>;<% end %>
<% if app[:min_instances] %>passenger_min_instances <%= app[:min_instances] %>;<% end %>
<% if app[:restart_dir] %>passenger_restart_dir '<%= app[:restart_dir] %>';<% end %>
<% if app[:sticky_sessions] %>passenger_sticky_sessions on;<% end %>
<% if app[:sticky_sessions_cookie_name] %>passenger_sticky_sessions_cookie_name '<%= app[:sticky_sessions_cookie_name] %>';<% end %>
<% if app[:vary_turbocache_by_cookie] %>passenger_vary_turbocache_by_cookie '<%= app[:vary_turbocache_by_cookie] %>';<% end %>
<% if app[:union_station_key] %>
union_station_support on;
union_station_key <%= app[:union_station_key] %>;
<% end %>
<% if app[:ssl] %>
ssl_certificate <%= app[:ssl_certificate] %>;
ssl_certificate_key <%= app[:ssl_certificate_key] %>;
<% end %>
<% if @options[:meteor_app_settings] %>
passenger_meteor_app_settings <%= @options[:meteor_app_settings] %>;
<% end %>
<% app[:envvars].each_pair do |name, value| %>
passenger_env_var '<%= name %>' '<%= value %>';
<% end %>
# Rails asset pipeline support.
location ~ "^/assets/.+-([0-9a-f]{32}|[0-9a-f]{64})\..+" {
error_page 490 = @static_asset;
error_page 491 = @dynamic_request;
recursive_error_pages on;
if (-f $request_filename) {
return 490;
}
if (!-f $request_filename) {
return 491;
}
}
location @static_asset {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header Access-Control-Allow-Origin "*";
add_header ETag "";
}
location @dynamic_request {
passenger_enabled on;
}
<% (ENV['NGINX_ADDITIONAL_SERVER_RULES'] || "").split(";").each do |rule| %>
<%= rule.chomp(";") %>;
<% end %>
}
passenger_pre_start <%= listen_url(app) %>;
<% end %>
}

@ -1,4 +1,5 @@
#!/bin/bash
set -e
pushd "${APP_PATH}/frontend"
@ -10,8 +11,8 @@ popd
# Bundle assets
DATABASE_URL='nulldb://nohost' RAILS_ENV=production bundle exec rake assets:precompile
# Remove frontend again
rm -rf "${APP_PATH}/frontend/node_modules"
# Remove node_modules and entire frontend
rm -rf "$APP_PATH/node_modules/" "$APP_PATH/frontend/node_modules/"
# Clean cache in root
rm -rf /root/.npm

@ -1,5 +1,5 @@
#!/bin/bash
set -e
[ -f /etc/apache2/sites-enabled/openproject.conf ] || erb -r time /usr/src/app/docker/proxy.conf.erb > /etc/apache2/sites-enabled/openproject.conf
[ -f /etc/apache2/sites-enabled/openproject.conf ] || erb -r time $APP_PATH/docker/proxy.conf.erb > /etc/apache2/sites-enabled/openproject.conf
exec /usr/sbin/apache2ctl -DFOREGROUND

@ -1,6 +1,6 @@
<VirtualHost *:80>
ServerName <%= ENV.fetch('SERVER_NAME') { "_default_" } %>
DocumentRoot /usr/src/app/public
DocumentRoot <%= ENV.fetch('APP_PATH') %>/public
ProxyRequests off

@ -0,0 +1,115 @@
#!/bin/bash
set -e
set -o pipefail
echo "-----> Starting the all-in-one OpenProject setup at $BASH_SOURCE..."
if [ "$PGDATA" == "" ]; then
echo "No PGDATA environment variable defined. Aborting."
exit 2
fi
PGUSER=${PGUSER:=postgres}
PGPASSWORD=${PGPASSWORD:=postgres}
PG_STARTUP_WAIT_TIME=${PG_STARTUP_WAIT_TIME:=10}
SUPERVISORD_LOG_LEVEL=${SUPERVISORD_LOG_LEVEL:=info}
PGBIN="/usr/lib/postgresql/9.6/bin"
dbhost=$(ruby -ruri -e 'puts URI(ENV.fetch("DATABASE_URL")).host')
pwfile=$(mktemp)
echo "$PGPASSWORD" > $pwfile
chown postgres $pwfile
PLUGIN_GEMFILE_TMP=$(mktemp)
PLUGIN_GEMFILE=$APP_PATH/Gemfile.local
if [ "$PLUGIN_GEMFILE_URL" != "" ]; then
echo "Fetching custom gemfile from ${PLUGIN_GEMFILE_URL}..."
curl -L -o "$PLUGIN_GEMFILE_TMP" "$PLUGIN_GEMFILE_URL"
# set custom plugin gemfile if file is readable and non-empty
if [ -s "$PLUGIN_GEMFILE_TMP" ]; then
mv "$PLUGIN_GEMFILE_TMP" "$PLUGIN_GEMFILE"
chown $APP_USER:$APP_USER "$PLUGIN_GEMFILE"
fi
fi
indent() {
sed -u 's/^/ /'
}
install_plugins() {
pushd $APP_PATH >/dev/null
if [ -s "$PLUGIN_GEMFILE" ]; then
echo "Installing plugins..."
bundle install
echo "Installing frontend dependencies..."
pushd $APP_PATH/frontend >/dev/null
if [ "$(id -u)" = '0' ]; then
su - $APP_USER -c "cd $APP_PATH/frontend && npm install"
else
npm install
fi
popd >/dev/null
echo "Precompiling new assets..."
bundle exec rake assets:precompile
echo "Plugins installed"
fi
popd >/dev/null
}
migrate() {
wait_for_postgres
pushd $APP_PATH >/dev/null
/etc/init.d/memcached start
bundle exec rake db:migrate db:seed db:structure:dump
/etc/init.d/memcached stop
chown "$APP_USER.$APP_USER" db/structure.sql
popd >/dev/null
}
wait_for_postgres() {
retries=${PG_STARTUP_WAIT_TIME}
echo "Trying to contact PostgreSQL server instance or waiting for it to come online."
until su postgres -c "$PGBIN/psql $DATABASE_URL -c 'select 1;' > /dev/null 2>&1" || [ $retries -eq 0 ]; do
echo "Waiting for postgres server, $((retries--)) remaining attempts..."
sleep 3
done
}
if [ "$dbhost" = "127.0.0.1" ]; then
# initialize cluster if it does not exist yet
if [ -f "$PGDATA/PG_VERSION" ]; then
echo "-----> Database cluster already exists, not modifying."
/etc/init.d/postgresql start | indent
(install_plugins && migrate) | indent
/etc/init.d/postgresql stop | indent
else
echo "-----> Database cluster not found. Creating a new one in $PGDATA..."
chown -R postgres:postgres $PGDATA
su postgres -c "$PGBIN/initdb --pgdata=${PGDATA} --username=${PGUSER} --encoding=unicode --auth=trust --pwfile=$pwfile" | indent
su postgres -c "rm -f $pwfile"
/etc/init.d/postgresql start | indent
su postgres -c "$PGBIN/psql --command \"CREATE USER openproject WITH SUPERUSER PASSWORD 'openproject';\"" | indent
su postgres -c "$PGBIN/createdb -O openproject openproject" | indent
(install_plugins && migrate) | indent
/etc/init.d/postgresql stop | indent
fi
else
echo "-----> You're using an external database. Not initializing a local database cluster."
migrate | indent
fi
echo "-----> Database setup finished."
echo " On first installation, the default admin credentials are login: admin, password: admin"
echo "-----> Launching supervisord..."
exec /usr/bin/supervisord -c $APP_PATH/docker/supervisord.conf -e ${SUPERVISORD_LOG_LEVEL}

@ -4,48 +4,60 @@ nodaemon=true
[program:web]
priority=4
user=app
environment=HOME="/home/app",USER="app"
directory=/usr/src/app
environment=HOME="/home/%(ENV_APP_USER)s",USER="%(ENV_APP_USER)s"
directory=%(ENV_APP_PATH)s
command=./docker/web
autorestart=true
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:worker]
priority=5
user=app
environment=HOME="/home/app",USER="app"
directory=/usr/src/app
environment=HOME="/home/%(ENV_APP_USER)s",USER="%(ENV_APP_USER)s"
directory=%(ENV_APP_PATH)s
command=./docker/worker
startretries=10
autorestart=true
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:memcached]
priority=100
user=app
environment=HOME="/home/app",USER="app"
environment=HOME="/home/%(ENV_APP_USER)s",USER="%(ENV_APP_USER)s"
command=/usr/bin/memcached
autorestart=true
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:cron]
priority=100
user=app
environment=HOME="/home/app",USER="app"
directory=/usr/src/app
environment=HOME="/home/%(ENV_APP_USER)s",USER="%(ENV_APP_USER)s"
directory=%(ENV_APP_PATH)s
command=./docker/cron
autostart=false
autorestart=true
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:apache2]
priority=2
directory=/usr/src/app
directory=%(ENV_APP_PATH)s
command=./docker/proxy
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:postfix]
priority=100
@ -53,13 +65,18 @@ directory=/etc/postfix
command=/usr/sbin/postfix -c /etc/postfix start
startsecs=0
autorestart=false
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0
[program:postgres]
user=postgres
priority=1
command=/usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf
command=/usr/lib/postgresql/9.6/bin/postgres -D %(ENV_PGDATA)s -c config_file=/etc/postgresql/9.6/main/postgresql.conf
autorestart=true
stderr_logfile = /var/log/supervisor/%(program_name)s-stderr.log
stdout_logfile = /var/log/supervisor/%(program_name)s-stdout.log
stderr_logfile = /dev/stderr
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

@ -1,161 +0,0 @@
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
cmdname=$(basename $0)
echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $TIMEOUT -gt 0 ]]; then
echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
else
echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
fi
start_ts=$(date +%s)
while :
do
(echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
result=$?
if [[ $result -eq 0 ]]; then
end_ts=$(date +%s)
echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
break
fi
sleep 1
done
return $result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $QUIET -eq 1 ]]; then
timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
else
timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
fi
PID=$!
trap "kill -INT -$PID" INT
wait $PID
RESULT=$?
if [[ $RESULT -ne 0 ]]; then
echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
fi
return $RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
hostport=(${1//:/ })
HOST=${hostport[0]}
PORT=${hostport[1]}
shift 1
;;
--child)
CHILD=1
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-s | --strict)
STRICT=1
shift 1
;;
-h)
HOST="$2"
if [[ $HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
HOST="${1#*=}"
shift 1
;;
-p)
PORT="$2"
if [[ $PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
PORT="${1#*=}"
shift 1
;;
-t)
TIMEOUT="$2"
if [[ $TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
CLI="$@"
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$HOST" == "" || "$PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
TIMEOUT=${TIMEOUT:-15}
STRICT=${STRICT:-0}
CHILD=${CHILD:-0}
QUIET=${QUIET:-0}
if [[ $CHILD -gt 0 ]]; then
wait_for
RESULT=$?
exit $RESULT
else
if [[ $TIMEOUT -gt 0 ]]; then
wait_for_wrapper
RESULT=$?
else
wait_for
RESULT=$?
fi
fi
if [[ $CLI != "" ]]; then
if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
echoerr "$cmdname: strict mode, refusing to execute subprocess"
exit $RESULT
fi
exec $CLI
else
exit $RESULT
fi

@ -19,5 +19,4 @@ exec bundle exec passenger start \
--min-instances "$MIN_INSTANCES" \
--max-pool-size "$MAX_INSTANCES" \
--spawn-method "$SPAWN_METHOD" \
--nginx-config-template "docker/nginx.conf.erb" \
--max-preloader-idle-time 0

Loading…
Cancel
Save