Alpinize + Dockerize Crisis Cleanup

This commit is contained in:
Disassembler 2017-12-25 11:43:06 +01:00
parent 4f0a1de88e
commit 639a253d80
16 changed files with 163 additions and 144 deletions

View File

@ -1,69 +1,44 @@
#!/bin/bash #!/bin/sh
SOURCE_DIR=$(realpath $(dirname "${0}"))/crisiscleanup SOURCE_DIR=$(realpath $(dirname "${0}"))/crisiscleanup
# Add NodeJS + Yarn repositories # Build Docker container
wget https://deb.nodesource.com/gpgkey/nodesource.gpg.key -O - | apt-key add - docker build -t crisiscleanup ${SOURCE_DIR}
wget https://dl.yarnpkg.com/debian/pubkey.gpg -O - | apt-key add -
echo 'deb https://deb.nodesource.com/node_8.x stretch main' > /etc/apt/sources.list.d/nodejs.list
echo 'deb https://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list
apt-get -y update
# Install CrisisCleanup dependecies
apt-get -y --no-install-recommends install build-essential curl libpq-dev nodejs ruby ruby-dev yarn zlib1g-dev
gem install bundler
# Clone CrisisCleanup git repository
git clone --depth 1 https://github.com/CrisisCleanup/crisiscleanup /srv/crisiscleanup
# Fix Ruby version dependencies
sed -i 's/2\.2\.5/2.3.3/' /srv/crisiscleanup/Gemfile
sed -i 's/rdoc (4\.2\.0)/rdoc (4.3.0)/' /srv/crisiscleanup/Gemfile.lock
# Create CrisisCleanup OS user
adduser --system --group --home /srv/crisiscleanup --shell /bin/bash crisis
chown -R crisis:crisis /srv/crisiscleanup/
# Install CrisisCleanup dependencies
sudo -u crisis -i bundle install --path /srv/crisiscleanup/vendor/bundle
sudo -u crisis -i npm install
sudo -u crisis -i yarn
# Create database # Create database
export CRISISCLEANUP_PWD=$(head -c 18 /dev/urandom | base64) export CRISISCLEANUP_PWD=$(head -c 18 /dev/urandom | base64)
envsubst <${SOURCE_DIR}/tmp/crisiscleanup-createdb.sql >/tmp/crisiscleanup-createdb.sql envsubst <${SOURCE_DIR}/createdb.sql | docker exec -i postgres psql
sudo -u postgres psql -f /tmp/crisiscleanup-createdb.sql
rm /tmp/crisiscleanup-createdb.sql # Copy existing config files into persistent storage
mkdir -p /srv/crisiscleanup/conf
chown 8005:8005 /srv/crisiscleanup/conf
docker run --rm -v /srv/crisiscleanup/conf:/mnt/config crisiscleanup cp -rp /srv/crisiscleanup/config/. /mnt/config
chown root:root /srv/crisiscleanup/conf
# Configure CrisisCleanup # Configure CrisisCleanup
export CRISISCLEANUP_SECRET=$(sudo -u crisis -i /srv/crisiscleanup/bin/rake secret)
export CRISISCLEANUP_ADMIN_USER="Admin" export CRISISCLEANUP_ADMIN_USER="Admin"
export CRISISCLEANUP_ADMIN_EMAIL="admin@example.com" export CRISISCLEANUP_ADMIN_EMAIL="admin@example.com"
export CRISISCLEANUP_ADMIN_PWD=$(head -c 12 /dev/urandom | base64) export CRISISCLEANUP_ADMIN_PWD=$(head -c 12 /dev/urandom | base64)
envsubst <${SOURCE_DIR}/srv/crisiscleanup/config/database.yml >/srv/crisiscleanup/config/database.yml envsubst <${SOURCE_DIR}/srv/crisiscleanup/conf/database.yml >/srv/crisiscleanup/conf/database.yml
envsubst <${SOURCE_DIR}/srv/crisiscleanup/config/secrets.yml >/srv/crisiscleanup/config/secrets.yml cp ${SOURCE_DIR}/srv/crisiscleanup/conf/boot.rb /srv/crisiscleanup/conf/boot.rb
envsubst <${SOURCE_DIR}/srv/crisiscleanup/config/initializers/devise.rb >/srv/crisiscleanup/config/initializers/devise.rb cp ${SOURCE_DIR}/srv/crisiscleanup/conf/initializers/devise.rb /srv/crisiscleanup/conf/initializers/devise.rb
envsubst <${SOURCE_DIR}/srv/crisiscleanup/db/seeds.rb >/srv/crisiscleanup/db/seeds.rb cp ${SOURCE_DIR}/srv/crisiscleanup/conf/environments/production.rb /srv/crisiscleanup/conf/environments/production.rb
cp ${SOURCE_DIR}/srv/crisiscleanup/config/environments/production.rb /srv/crisiscleanup/config/environments/production.rb
cp ${SOURCE_DIR}/srv/crisiscleanup/.env /srv/crisiscleanup/.env
rm /srv/crisiscleanup/.env.test
sudo -u crisis -i /srv/crisiscleanup/bin/rake assets:precompile RAILS_ENV=production
# Populate database # Populate database
sudo -u crisis -i /srv/crisiscleanup/bin/rake db:schema:load RAILS_ENV=production envsubst <${SOURCE_DIR}/srv/crisiscleanup/db/seeds.rb >/tmp/seeds.rb
sudo -u crisis -i /srv/crisiscleanup/bin/rake db:seed RAILS_ENV=production docker run --rm --link=postgres -v /srv/crisiscleanup/conf:/srv/crisiscleanup/config crisiscleanup rake db:schema:load
docker run --rm --link=postgres -v /srv/crisiscleanup/conf:/srv/crisiscleanup/config -v /tmp/seeds.rb:/srv/crisiscleanup/db/seeds.rb crisiscleanup rake db:seed
rm /tmp/seeds.rb
# Create Rails service # Create Rails service
cp ${SOURCE_DIR}/lib/systemd/system/crisiscleanup.service /lib/systemd/system/crisiscleanup.service cp ${SOURCE_DIR}/etc/init.d/crisiscleanup /etc/init.d/crisiscleanup
systemctl daemon-reload rc-update add crisiscleanup boot
service crisiscleanup start
# Create nginx site definition # Create nginx app definition
cp ${SOURCE_DIR}/etc/nginx/sites-available/crisiscleanup /etc/nginx/sites-available/crisiscleanup cp ${SOURCE_DIR}/etc/nginx/apps/crisiscleanup /etc/nginx/apps/crisiscleanup
ln -s /etc/nginx/sites-available/crisiscleanup /etc/nginx/sites-enabled/crisiscleanup cp ${SOURCE_DIR}/etc/nginx/conf.d/crisiscleanup.conf /etc/nginx/conf.d/crisiscleanup.conf
service nginx reload
# Restart services
systemctl start crisiscleanup
systemctl restart nginx
# Add portal application definition # Add portal application definition
portal-app-manager crisis-cleanup "https://{host}:8005/" "${CRISISCLEANUP_ADMIN_EMAIL}" "${CRISISCLEANUP_ADMIN_PWD}" portal-app-manager crisis-cleanup "https://{host}:8405/" "${CRISISCLEANUP_ADMIN_EMAIL}" "${CRISISCLEANUP_ADMIN_PWD}"

74
crisiscleanup/Dockerfile Normal file
View File

@ -0,0 +1,74 @@
FROM alpine:3.7
MAINTAINER Disassembler <disassembler@dasm.cz>
RUN \
# Install Ruby runtime dependencies
apk --no-cache add gdbm libressl readline zlib \
# Install Ruby build dependencies
&& apk --no-cache add --virtual .deps build-base autoconf gdbm-dev libressl-dev linux-headers readline-dev zlib-dev \
# Download and unpack Ruby
&& wget http://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.6.tar.xz -O ruby.tar.xz \
&& mkdir -p /usr/src/ruby \
&& tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1 \
&& rm ruby.tar.xz \
&& cd /usr/src/ruby \
# Hackfix to suppress "Insecure world writable dir" warning
&& sed -ni 'p;13a #define ENABLE_PATH_CHECK 0' file.c \
# Configure compilation + hackfix to detect isnan/isinf macros
&& autoconf \
&& ac_cv_func_isnan=yes ac_cv_func_isinf=yes ./configure --build=x86_64-linux-musl --disable-install-doc --enable-shared \
# Compile and install Ruby
&& make -j $(nproc) \
&& make install \
# Install RubyGems and Bundler
&& mkdir -p /usr/local/etc \
&& echo -e 'install: --no-document\nupdate: --no-document' >/usr/local/etc/gemrc \
&& gem update --system \
# Cleanup
&& cd /tmp \
&& rm -r /usr/src/ruby \
&& apk --no-cache del .deps \
&& rm -rf /root \
&& mkdir /root
ENV RAILS_ENV production
RUN \
# Install runtime dependencies
apk --no-cache add libpq libxml2 libxslt nodejs tzdata \
# Install build dependencies
&& apk --no-cache add --virtual .deps build-base git libxml2-dev libxslt-dev linux-headers paxctl postgresql-dev yarn zlib-dev \
# Fix grsec attributes to loosen memory protection restrictions
&& paxctl -cm /usr/bin/node \
# Clone CrisisCleanup
&& git clone --depth 1 https://github.com/CrisisCleanup/crisiscleanup /srv/crisiscleanup \
# Hackfix ruby dependency versions
&& sed -i 's/2\.2\.5/2.3.6/' /srv/crisiscleanup/Gemfile \
&& sed -i 's/rdoc (4\.2\.0)/rdoc (4.3.0)/' /srv/crisiscleanup/Gemfile.lock \
# Install Ruby and NodeJS dependencies
&& cd /srv/crisiscleanup \
&& bundle config build.nokogiri --use-system-libraries \
&& bundle install \
&& npm install \
&& yarn \
# Create CrisisCleanup secret
&& echo -e "production:\n secret_key_base: $(rake secret)" >/srv/crisiscleanup/config/secrets.yml \
# Generate static resources
&& rake assets:precompile \
# Create OS user
&& addgroup -S -g 8005 crisiscleanup \
&& adduser -S -u 8005 -h /srv/crisiscleanup -s /bin/false -g crisiscleanup -G crisiscleanup crisiscleanup \
&& chown -R crisiscleanup:crisiscleanup /srv/crisiscleanup \
# Cleanup
&& apk --no-cache del .deps \
&& rm -rf /srv/crisiscleanup/.git* \
&& rm -rf /usr/local/share/.cache \
&& rm -rf /root \
&& mkdir /root
VOLUME ["/srv/crisiscleanup/config"]
EXPOSE 8005
USER crisiscleanup
WORKDIR /srv/crisiscleanup
CMD ["rails", "server"]

View File

@ -0,0 +1,17 @@
#!/sbin/openrc-run
description="Crisis Cleanup docker container"
depend() {
need docker net
use dns logger netmount
after postgres
}
start() {
/usr/bin/docker run -d --rm --name crisiscleanup --link=postgres -p 127.0.0.1:9005:8005 -v /srv/crisiscleanup/conf:/srv/crisiscleanup/config crisiscleanup
}
stop() {
/usr/bin/docker stop crisiscleanup
}

View File

@ -0,0 +1,9 @@
access_log /var/log/nginx/crisiscleanup.access.log;
error_log /var/log/nginx/crisiscleanup.error.log;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:9005;
}

View File

@ -0,0 +1,11 @@
server {
listen 8005;
listen [::]:8005;
include apps/crisiscleanup;
}
server {
listen 8405 ssl http2;
listen [::]:8405 ssl http2;
include apps/crisiscleanup;
}

View File

@ -1,20 +0,0 @@
server {
listen 8005 ssl http2;
listen [::]:8005 ssl http2;
access_log /var/log/nginx/crisiscleanup.access.log;
error_log /var/log/nginx/crisiscleanup.error.log;
root /srv/crisiscleanup/public;
try_files $uri/index.html $uri @crisiscleanup;
location @crisiscleanup {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:3000;
}
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
}

View File

@ -1,11 +0,0 @@
[Unit]
Description=Crisis Cleanup Ruby on Rails server
After=network.target
[Service]
User=crisis
WorkingDirectory=/srv/crisiscleanup
ExecStart=/srv/crisiscleanup/bin/rails server -b 127.0.0.1 -p 3000 -e production
[Install]
WantedBy=multi-user.target

View File

@ -1,2 +0,0 @@
COMPOSE_PROJECT_NAME=crisiscleanup
GOOGLE_MAPS_API_KEY=AIzaSyBvIF3D550tlpL6o1xRrDurGo-81VhHlOw

View File

@ -0,0 +1,15 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
ENV['GOOGLE_MAPS_API_KEY'] = 'AIzaSyBvIF3D550tlpL6o1xRrDurGo-81VhHlOw'
require 'bundler/setup' # Set up gems listed in the Gemfile.
require 'rails/commands/server'
module Rails
class Server
alias :default_options_bk :default_options
def default_options
default_options_bk.merge!(Host: '0.0.0.0', Port: 8005)
end
end
end

View File

@ -0,0 +1,8 @@
production:
adapter: postgresql
encoding: unicode
database: crisiscleanup
pool: 5
host: postgres
username: crisiscleanup
password: ${CRISISCLEANUP_PWD}

View File

@ -50,7 +50,7 @@ Rails.application.configure do
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true config.force_ssl = false
# Use the lowest log level to ensure availability of diagnostic information # Use the lowest log level to ensure availability of diagnostic information
# when problems arise. # when problems arise.

View File

@ -4,7 +4,7 @@ Devise.setup do |config|
# The secret key used by Devise. Devise uses this key to generate # The secret key used by Devise. Devise uses this key to generate
# random tokens. Changing this key will render invalid all existing # random tokens. Changing this key will render invalid all existing
# confirmation, reset password and unlock tokens in the database. # confirmation, reset password and unlock tokens in the database.
config.secret_key = '${CRISISCLEANUP_SECRET}' # config.secret_key = 'bb59fcb0f0a1b46483a9f7f52259c70114db2dd164686243ee5fee9abb18e1f5088e651c8d627e505db5d60691af3586de4b9a6f49cdeaeca59e5946a7726e52'
# ==> Mailer Configuration # ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer, # Configure the e-mail address which will be shown in Devise::Mailer,

View File

@ -1,31 +0,0 @@
development: &development
adapter: postgresql
encoding: unicode
database: crisiscleanup_development
pool: 5
username: crisiscleanup
password: crisiscleanup
host: localhost
port: 5432
docker:
<<: *development
host: postgres
test:
adapter: postgresql
encoding: unicode
database: crisiscleanup_test
pool: 5
username: crisiscleanup
password: crisiscleanup
host: localhost
port: 5432
production:
adapter: postgresql
encoding: unicode
database: crisiscleanup
pool: 5
username: crisiscleanup
password: ${CRISISCLEANUP_PWD}

View File

@ -1,25 +0,0 @@
# Be sure to restart your server when you modify this file.
# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
development:
secret_key_base: 57e62ae63822f461997fa79e75462ba7316c44e03c80d003ef9f68b572b8755cb5a7221e6c4b4958f995c2b03a82112941ee8951b9f393e5ca2449ab480b572b
docker:
secret_key_base: a6a0606f1a506b1a9e0059a1db833f2ee3d07ce86e2f938af1f5c0c120b2f5af73965610357edfb82afc90b024ed2ac7f39f25b38d3570d9e3cb76d4d096861b
test:
secret_key_base: 055f7b3ef374b2c1c7469fab62d9bc38a8dc510b9f314cc401b75e52974b1422f7796e27d8ff1594468c65ee04493c13a249bcaf77a18e75f96ddec5dbd36ce9
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: ${CRISISCLEANUP_SECRET}

View File

@ -19,6 +19,5 @@ Legacy::LegacySite.create!([
{address: "200 Epcot Center Drive", blurred_latitude: 28.3849506927356, blurred_longitude: -81.5443968549352, case_number: "A7", city: "Orlando", claimed_by: 2, legacy_event_id: 1, latitude: 28.383045, longitude: -81.5485919, name: "Timothy Schmidt", phone1: "1234567890", reported_by: 2, requested_at: nil, state: "Florida", status: "Open, unassigned", work_type: "Debris", data: {"email"=>"", "notes"=>"", "habitable"=>"n", "assigned_to"=>"", "electricity"=>"n", "prepared_by"=>"", "rent_or_own"=>"", "unsafe_roof"=>"n", "cross_street"=>"", "status_notes"=>"", "time_to_call"=>"", "older_than_60"=>"n", "other_hazards"=>"", "roof_collapse"=>"n", "special_needs"=>"", "num_trees_down"=>"0", "num_wide_trees"=>"0", "chainsaw_needed"=>"n", "first_responder"=>"n", "autofill_disable"=>"", "electrical_lines"=>"n", "total_volunteers"=>"", "destruction_level"=>"", "meal_location_poc"=>"", "do_not_work_before"=>"", "meal_serving_times"=>"", "structural_problems"=>"n", "required_daily_meals"=>"", "work_without_resident"=>"n", "interior_debris_removal"=>"n", "unsalvageable_structure"=>"n", "heavy_machinary_required"=>"n", "vegitative_debris_removal"=>"n", "hours_worked_per_volunteer"=>"", "initials_of_resident_present"=>"", "nonvegitative_debris_removal"=>"n", "member_of_assessing_organization"=>"n"}, request_date: "2017-09-18", appengine_key: nil, zip_code: "32821", county: "Orange County", phone2: "", work_requested: "", name_metaphone: "TM0 SXMTT", city_metaphone: "ORLNT", county_metaphone: "ORNJ KNT", address_metaphone: " EPKT SNTR TRF", user_id: 2} {address: "200 Epcot Center Drive", blurred_latitude: 28.3849506927356, blurred_longitude: -81.5443968549352, case_number: "A7", city: "Orlando", claimed_by: 2, legacy_event_id: 1, latitude: 28.383045, longitude: -81.5485919, name: "Timothy Schmidt", phone1: "1234567890", reported_by: 2, requested_at: nil, state: "Florida", status: "Open, unassigned", work_type: "Debris", data: {"email"=>"", "notes"=>"", "habitable"=>"n", "assigned_to"=>"", "electricity"=>"n", "prepared_by"=>"", "rent_or_own"=>"", "unsafe_roof"=>"n", "cross_street"=>"", "status_notes"=>"", "time_to_call"=>"", "older_than_60"=>"n", "other_hazards"=>"", "roof_collapse"=>"n", "special_needs"=>"", "num_trees_down"=>"0", "num_wide_trees"=>"0", "chainsaw_needed"=>"n", "first_responder"=>"n", "autofill_disable"=>"", "electrical_lines"=>"n", "total_volunteers"=>"", "destruction_level"=>"", "meal_location_poc"=>"", "do_not_work_before"=>"", "meal_serving_times"=>"", "structural_problems"=>"n", "required_daily_meals"=>"", "work_without_resident"=>"n", "interior_debris_removal"=>"n", "unsalvageable_structure"=>"n", "heavy_machinary_required"=>"n", "vegitative_debris_removal"=>"n", "hours_worked_per_volunteer"=>"", "initials_of_resident_present"=>"", "nonvegitative_debris_removal"=>"n", "member_of_assessing_organization"=>"n"}, request_date: "2017-09-18", appengine_key: nil, zip_code: "32821", county: "Orange County", phone2: "", work_requested: "", name_metaphone: "TM0 SXMTT", city_metaphone: "ORLNT", county_metaphone: "ORNJ KNT", address_metaphone: " EPKT SNTR TRF", user_id: 2}
]) ])
User.create!([ User.create!([
{email: "${CRISISCLEANUP_ADMIN_EMAIL}", password: "${CRISISCLEANUP_ADMIN_PWD}", name: "${CRISISCLEANUP_ADMIN_USER}", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, legacy_organization_id: 1, current_sign_in_at: "2016-07-15 03:45:59", last_sign_in_at: "2016-06-08 16:56:37", current_sign_in_ip: "1.1.1.1", last_sign_in_ip: "173.164.56.105", referring_user_id: nil, admin: true, role: nil, mobile: nil, accepted_terms: true, accepted_terms_timestamp: "2017-09-18 20:46:31", title: nil}, {email: "${CRISISCLEANUP_ADMIN_EMAIL}", password: "${CRISISCLEANUP_ADMIN_PWD}", name: "${CRISISCLEANUP_ADMIN_USER}", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, legacy_organization_id: 1, current_sign_in_at: "2016-07-15 03:45:59", last_sign_in_at: "2016-06-08 16:56:37", current_sign_in_ip: "1.1.1.1", last_sign_in_ip: "173.164.56.105", referring_user_id: nil, admin: true, role: nil, mobile: nil, accepted_terms: true, accepted_terms_timestamp: "2017-09-18 20:46:31", title: nil}
{email: "demo@crisiscleanup.org", password: "password", name: "Demo User", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 2, legacy_organization_id: 2, current_sign_in_at: "2017-09-18 20:47:11", last_sign_in_at: "2017-09-18 14:22:32", current_sign_in_ip: "::1", last_sign_in_ip: "1.1.1.1", referring_user_id: 1, admin: false, role: "Primary Contact", mobile: "555-555-5555", accepted_terms: true, accepted_terms_timestamp: "2017-09-18 20:47:11", title: "Manager"}
]) ])