Skip to content

Commit

Permalink
Improve Docker setup
Browse files Browse the repository at this point in the history
  • Loading branch information
wvengen committed Sep 9, 2017
1 parent f8662c9 commit f619125
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 107 deletions.
43 changes: 37 additions & 6 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,43 @@
.git
.idea
.sass-cache
.gitignore

.bundle
.rake_tasks*
db/*.sqlite3
log
config/database.yml
doc
node_modules
tmp/*
public/assets
public/system
tmp/*
public/uploads
vendor/bundle

# no configuration
config/*.yml
!config/i18n-js.yml

# IDEs, Developer tools
.idea
.loadpath
.project
.sass-cache
.rbenv-version
.get-dump.yml
.bash_history
.localeapp
nbproject/
*.swp
*~

coverage
*.sql*
tags
doc/app/
doc/api/
.yarddoc/
rspec.failures

# Capistrano etc.
Capfile
config/deploy
config/deploy.rb
Gemfile.capistrano*
48 changes: 32 additions & 16 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
log/*.log
tmp/**/*
config/app_config.yml
config/database.yml
config/initializers/secret_token.rb
.bundle
.rake_tasks*
db/*.sqlite3
nbproject/
log
node_modules
tmp
public/assets
public/system
public/uploads
vendor/bundle

# no configuration
config/*.yml
!config/i18n-js.yml
config/environments/development.rb
*.swp
*~
public/**/*_cached.*

# IDEs, Developer tools
.idea
.loadpath
.project
.sass-cache
.rbenv-version
.get-dump.yml
.sass-cache/
.bash_history
.localeapp
nbproject/
*.swp
*~

coverage
tags
doc/app/
doc/api/
.yarddoc/
# Deployment tools
rspec.failures

# Capistrano etc.
Capfile
config/deploy
config/deploy.rb
config/deploy/*
.localeapp
log/localeapp.yml
.bundle
rspec.failures
Gemfile.capistrano*
67 changes: 41 additions & 26 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,45 +1,60 @@
FROM ruby:2.3

RUN apt-get update && \
apt-get install --no-install-recommends -y cron && \
rm -rf /var/lib/apt/lists/* && \
apt-get clean
RUN SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.1.3/supercronic-linux-amd64 && \
SUPERCRONIC_BIN=/usr/local/bin/supercronic && \
SUPERCRONIC_SHA1SUM=96960ba3207756bb01e6892c978264e5362e117e && \
curl -fsSL -o "${SUPERCRONIC_BIN}" "${SUPERCRONIC_URL}" \
&& echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC_BIN}" | sha1sum -c - \
&& chmod +x "${SUPERCRONIC_BIN}"

ENV RAILS_ENV=production \
RAILS_LOG_TO_STDOUT=true \
RAILS_SERVE_STATIC_FILES=true

WORKDIR /usr/src/app
COPY . ./
RUN echo $SOURCE_COMMIT > REVISION

RUN buildDeps='libmagic-dev' && \
# separately from rest of the code to avoid re-running bundler when Gemfile doesn't change
# plugins is copied completely, because COPY can't pick wildcard directories
COPY plugins plugins/
COPY Gemfile Gemfile.lock ./

RUN BUILD_DEPS='libmagic-dev' && \
apt-get update && \
apt-get install --no-install-recommends -y $buildDeps && \
rm -rf /var/lib/apt/lists/* && \
bundle install --deployment --without development test && \
apt-get purge -y --auto-remove $buildDeps && \
echo "Foodsoft::Application.config.secret_token = ENV['SECRET_KEY_BASE']" > config/initializers/secret_token.rb && \
mkdir -p log && \
ln -sfn /dev/stdout log/production.log && \
bundle exec whenever --update-crontab

# Add a temporary mysql-server for assets precompilation
apt-get install --no-install-recommends -y $BUILD_DEPS && \
echo 'gem: --no-document' >> ~/.gemrc && \
bundle config --global build.nokogiri "--use-system-libraries" && \
bundle install --deployment --without development test -j 4 && \
apt-get purge -y --auto-remove $BUILD_DEPS && \
rm -Rf /var/lib/apt/lists/* /var/cache/apt/*

COPY . ./

RUN mv config/app_config.yml.SAMPLE config/app_config.yml

# compile assets with temporary mysql server
RUN export DATABASE_URL=mysql2://localhost/temp && \
export SECRET_KEY_BASE=thisisnotimportantnow && \
export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y mysql-server && \
/etc/init.d/mysql start && \
cp config/app_config.yml.SAMPLE config/app_config.yml && \
bundle exec rake db:setup && \
bundle exec rake assets:precompile && \
rm config/app_config.yml && \
rm -rf tmp/* && \
bundle exec rake db:setup assets:precompile && \
rm -Rf tmp/* && \
/etc/init.d/mysql stop && \
rm -rf /run/mysqld /tmp/* /var/lib/mysql /var/log/mysql* && \
rm -Rf /run/mysqld /tmp/* /var/lib/mysql /var/log/mysql* && \
apt-get purge -y --auto-remove mysql-server && \
rm -rf /var/lib/apt/lists/*
rm -Rf /var/lib/apt/lists/* /var/cache/apt/*

RUN bundle exec whenever >crontab

# Make relevant dirs writable for app user
RUN mkdir -p tmp && \
chown nobody tmp

# Run app as unprivileged user
USER nobody

EXPOSE 3000

ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["rails", "server", "--binding", "0.0.0.0"]
# start web process from Procfile
CMD ["script/start", "web"]
4 changes: 4 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
web: bundle exec rails server --binding 0.0.0.0 --port $PORT
worker: QUEUE=foodsoft_notifier bundle exec rake resque:work
mail: bundle exec rake foodsoft:reply_email_smtp_server
cron: supercronic crontab
10 changes: 8 additions & 2 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
# 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.
config.force_ssl = true
config.force_ssl = ENV["RAILS_FORCE_SSL"] != "false"

# Set to :debug to see everything in the log.
config.log_level = :info
Expand All @@ -49,7 +49,13 @@
# config.log_tags = [ :subdomain, :uuid ]

# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# https://github.com/heroku/rails_12factor/issues/25#issuecomment-231103483
if ENV["RAILS_LOG_TO_STDOUT"].present?
STDOUT.sync = true
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end

# Use a different cache store in production.
# config.cache_store = :mem_cache_store
Expand Down
25 changes: 25 additions & 0 deletions config/initializers/secret_token.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Be sure to restart your server when you modify this file.

# Your secret key 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.
Foodsoft::Application.config.secret_key_base = begin
if (token = ENV['SECRET_KEY_BASE']).present?
token
elsif Rails.env.production? || Rails.env.staging?
raise "You must set SECRET_KEY_BASE"
elsif Rails.env.test?
SecureRandom.hex(30) # doesn't really matter
else
sf = Rails.root.join('tmp', 'secret_key_base')
if File.exists?(sf)
File.read(sf)
else
puts "=> Generating initial SECRET_KEY_BASE in #{sf}"
token = SecureRandom.hex(30)
File.open(sf, 'w') { |f| f.write(token) }
token
end
end
end
10 changes: 0 additions & 10 deletions config/initializers/secret_token.rb.SAMPLE

This file was deleted.

17 changes: 3 additions & 14 deletions doc/SETUP_DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,26 +141,15 @@ explained here.
Edit `app_config.yml` to suit your needs or just keep the defaults for now.


4. **Secret token**

The user session are stored in cookies. Do avoid misusing the cookies and
its sensitive information, rails will encrypt it with a token. So copy the
config file

cp config/initializers/secret_token.rb.SAMPLE config/initializers/secret_token.rb

and modify the token!! You can run `bundle exec rake secret`


5. **Create database (schema) and load defaults**
4. **Create database (schema) and load defaults**

rake db:setup

With this, you also get a ready to go user with username 'admin' and
password 'secret'.


6. (optional) Get **background jobs** done
5. (optional) Get **background jobs** done

Time intensive tasks may block the web request. To run these in a separate
task, you can install Redis and enable Resque:
Expand All @@ -173,7 +162,7 @@ explained here.
`resque-web`.


7. (optional) **View mails in browser** instead in your logs
6. (optional) **View mails in browser** instead in your logs

We use mailcatcher in development mode to view all delivered mails in a
browser interface. Just install mailcatcher with gem install mailcatcher
Expand Down
21 changes: 0 additions & 21 deletions docker-entrypoint.sh

This file was deleted.

12 changes: 0 additions & 12 deletions lib/tasks/foodsoft_setup.rake
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ namespace :foodsoft do
setup_app_config
setup_development
setup_database
setup_secret_token
start_mailcatcher
puts yellow "All done! Your foodcoft should be running smoothly."
start_server
Expand All @@ -44,7 +43,6 @@ namespace :foodsoft do
task :stock_config do
setup_app_config
setup_development
setup_secret_token
end
end
end
Expand Down Expand Up @@ -103,16 +101,6 @@ def setup_development
reminder(file)
end

def setup_secret_token
file = 'config/initializers/secret_token.rb'
return nil if skip?(file)

puts yellow "Generating secret_token and writing to #{file}..."
Rake::Task["secret"].reenable
secret = capture_stdout { Rake::Task["secret"].invoke }
%x( touch #{Rails.root.join("#{file}")}; echo 'Foodsoft::Application.config.secret_key_base = "#{secret.chomp}"' > #{Rails.root.join("#{file}")} )
end

def start_mailcatcher
return nil if ENV['MAILCATCHER_PORT'] # skip when it has an existing Docker container
mailcatcher = ask("Do you want to start mailcatcher?\nOptions:\n(y) Yes\n(n) No", ["y","n"])
Expand Down
21 changes: 21 additions & 0 deletions script/start
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh
#
# Run single command from Procfile
#
if [ ! "$1" ]; then
echo "Usage: $0 <process type>" 1>&2
exit 1
fi

PROCFILE=`dirname "$0"`/../Procfile
CMD=`cat "$PROCFILE" | grep "^$1:" | cut -d: -f2-`
if [ ! "$CMD" ]; then
echo "Process name $1 not found in Procfile" 1>&2
exit 2
fi

PS="$1"
[ "$PORT" ] || PORT=3000
export PS PORT

exec /bin/sh -c "$CMD"

0 comments on commit f619125

Please sign in to comment.