Move back to docker-compose + fix env vars

Fix env vars. Rely on inheritance.
Add a script to load env vars as above.
Fix staging env
Add nginx conf and SSL directory
Reorganize .gitignore
Use multi-staged docker-compose + dockerfile
Substitute env vars for static values
This commit is contained in:
Ari Timonen 2020-04-05 05:58:41 +03:00
parent 98db32e0fb
commit 75b33e760a
23 changed files with 373 additions and 508 deletions

View file

@ -1,6 +1,12 @@
Dockerfile Dockerfile
db_data docker-compose.yml
db/data/ *.md
.idea
dkim dkim
log/* log/.log*
tmp/
public/* public/*
db_data
db/data
db/initdb.d/
ext/

View file

@ -1,31 +1,11 @@
# This file is actually loaded by Dotenv when RAILS_ENV=development # This file is actually loaded by Dotenv when RAILS_ENV=development
# Development-specific ENV variables, loaded after .env and before .env*local
# Add changes only specific to dev. env.
# These are
RACK_ENV=development RACK_ENV=development
RAILS_ENV=development RAILS_ENV=development
APP_SECRET=fe837ea72667ec3d8ecb94cfba1a1bba
DEPLOY_PATH=/var/www
FILES_PATH=/var/www/public/files
PUMA_WORKERS=0
PUMA_MIN_THREADS=1
PUMA_MAX_THREADS=16
PUMA_PORT=4000
# Set this to higher to enable debugging # Set this to higher to enable debugging
PUMA_TIMEOUT=300 PUMA_TIMEOUT=300
MYSQL_HOST=db
MYSQL_DATABASE=ensl
MYSQL_USERNAME=ensl
MYSQL_PASSWORD=ensl
MYSQL_ROOT_PASSWORD=ensl
MYSQL_CONNECTION_POOL=32
NEW_RELIC_APP_NAME=ENSL
NEW_RELIC_LICENSE_KEY=
GOOGLE_API_KEY=
GOOGLE_CALENDAR_ID=
GOOGLE_CALENDAR=enabled

View file

@ -1,62 +0,0 @@
# Read https://github.com/bkeepers/dotenv
# This is just a sample file
# Change this depending where you are
RACK_ENV=production
RAILS_ENV=production
# App secret for cookie encryption
APP_SECRET=randomstringhere
# Use
# SCrypt::Engine.calibrate!(max_mem: 16 * 1024 * 1024)
# SCrypt::Engine.generate_salt
SCRYPT_SALT_OPTS=
SCRYPT_MAX_TIME=1
# Since this is inside Docker container, it doesn't really matter
DEPLOY_PATH=/var/www
# Puma fails in cluster mode, so use 0 workers
PUMA_WORKERS=0
# Threads and port
PUMA_MIN_THREADS=1
PUMA_MAX_THREADS=16
PUMA_PORT=4000
# Use higher timeout if debug fails
PUMA_TIMEOUT=30
# Path to files
FILES_PATH=/var/www/files
# Docker adds mysql to hosts
MYSQL_HOST=db
# This is used by both rails + mysql
MYSQL_DATABASE=ensl
# Add to allow docker image to connect
MYSQL_ROOT_HOST=%
# Root MySQL password
MYSQL_ROOT_PASSWORD=ensl
# These are for ENSL, edit at least password
MYSQL_USERNAME=ensl
MYSQL_PASSWORD=ensl
# More MySQL vars
MYSQL_CONNECTION_POOL=32
SELENIUM_HOST=selenium
TEST_APP_HOST=localhost
TEST_APP_PORT=3005
NEW_RELIC_APP_NAME=ENSL
NEW_RELIC_LICENSE_KEY=
GOOGLE_API_KEY=
GOOGLE_CALENDAR_ID=
GOOGLE_CALENDAR=enabled

View file

@ -3,8 +3,6 @@
RACK_ENV=production RACK_ENV=production
RAILS_ENV=production RAILS_ENV=production
DEPLOY_PATH=/var/www
# FIXME Disable workers + cluster mode for now. # FIXME Disable workers + cluster mode for now.
PUMA_WORKERS=0 PUMA_WORKERS=0
PUMA_MIN_THREADS=1 PUMA_MIN_THREADS=1
@ -12,9 +10,9 @@ PUMA_MAX_THREADS=32
PUMA_PORT=4000 PUMA_PORT=4000
PUMA_TIMEOUT=30 PUMA_TIMEOUT=30
MYSQL_HOST=db
MYSQL_DATABASE=ensl MYSQL_DATABASE=ensl
MYSQL_USERNAME=ensl
MYSQL_CONNECTION_POOL=48 MYSQL_CONNECTION_POOL=48
APP_DOMAIN=ensl.org
GOOGLE_CALENDAR=enabled GOOGLE_CALENDAR=enabled

View file

@ -1,31 +1,10 @@
# This file is actually loaded by Dotenv when RAILS_ENV=development # This file is actually loaded by Dotenv when RAILS_ENV=development
RACK_ENV=development RACK_ENV=staging
RAILS_ENV=development RAILS_ENV=staging
APP_SECRET=fe837ea72667ec3d8ecb94cfba1a1bba APP_PORT=4999
APP_PORT_SSL=5000
PUMA_PORT=5000
DEPLOY_PATH=/var/www
FILES_PATH=/var/www/public/files
PUMA_WORKERS=0
PUMA_MIN_THREADS=1
PUMA_MAX_THREADS=16
PUMA_PORT=4000
# Set this to higher to enable debugging
PUMA_TIMEOUT=30
MYSQL_HOST=db
MYSQL_DATABASE=ensl_staging MYSQL_DATABASE=ensl_staging
MYSQL_USERNAME=ensl
MYSQL_PASSWORD=ensl
MYSQL_ROOT_PASSWORD=ensl
MYSQL_CONNECTION_POOL=32
NEW_RELIC_APP_NAME=ENSL
NEW_RELIC_LICENSE_KEY=
GOOGLE_API_KEY=
GOOGLE_CALENDAR_ID=
GOOGLE_CALENDAR=enabled

View file

@ -7,9 +7,6 @@ APP_SECRET=fe837ea72667ec3d8ecb94cfba1a1bba
DEPLOY_PATH=/var/www DEPLOY_PATH=/var/www
PUMA_WORKERS=1
PUMA_MIN_THREADS=1
PUMA_MAX_THREADS=16
PUMA_PORT=4000 PUMA_PORT=4000
PUMA_TIMEOUT=30 PUMA_TIMEOUT=30
@ -17,21 +14,8 @@ SELENIUM_HOST=selenium
TEST_APP_HOST=localhost TEST_APP_HOST=localhost
TEST_APP_PORT=3005 TEST_APP_PORT=3005
MYSQL_HOST=db
MYSQL_DATABASE=ensl_test MYSQL_DATABASE=ensl_test
MYSQL_USER=ensl
MYSQL_USERNAME=ensl
MYSQL_PASSWORD=ensl
MYSQL_ROOT_PASSWORD=ensl
MYSQL_CONNECTION_POOL=8
NEW_RELIC_APP_NAME=ENSL
NEW_RELIC_LICENSE_KEY=
# Fix poltergeist issue # Fix poltergeist issue
CLIVER_NO_VERIFY=1 CLIVER_NO_VERIFY=1
OPENSSL_CONF=/etc/ssl/ OPENSSL_CONF=/etc/ssl/
GOOGLE_API_KEY=
GOOGLE_CALENDAR_ID=
GOOGLE_CALENDAR=enabled

53
.gitignore vendored
View file

@ -2,14 +2,14 @@
/log/* /log/*
/tmp/* /tmp/*
/spec/tmp/* /spec/tmp/*
/env/production.sh
/env/development.sh
.ruby-version .ruby-version
.ruby-gemset .ruby-gemset
.env .env
.env*.local .env*.local
.tmp* .tmp*
.rspec .rspec
# Cache files
.sass-cache .sass-cache
*.sassc *.sassc
*.rbc *.rbc
@ -26,38 +26,27 @@ db/initdb.d/*
# ignore dkim keys # ignore dkim keys
dkim dkim
ext/dkim
# OS X # ignore SSL
.DS_Store ext/ssl
!ext/ssl/.placeholder
# Nginx
ext/nginx.conf.d/default.conf
# Uploaded Assets # Uploaded Assets
/public/system/* /public/system/*
/public/files/* /public/files
/public/local /public/local
/public/uploads /public/uploads
/public/assets /public/assets
# RubyMine
/.idea
# VIM
**.swp
# Git junk
**.orig
# Bundler # Bundler
/.bundle /.bundle
/vendor/bundle/ /vendor/bundle/
.bundle .bundle
# Misc
/coverage/
/backups
/index/*
rerun.txt
pickle-email-*.html
# Direnv # Direnv
.envrc .envrc
@ -69,10 +58,28 @@ pickle-email-*.html
.rakeTasks .rakeTasks
.generators .generators
# OS X
.DS_Store
# RubyMine
.idea/
# VIM
**.swp
# Git junk
**.orig
# Misc
/coverage/
/backups
/index/*
rerun.txt
pickle-email-*.html
# Gemtags # Gemtags
*.tags *.tags
*.gemtags *.gemtags
# Staging files # Debug files
tmp/*.gz
.byebug_history .byebug_history

View file

@ -6,7 +6,7 @@ Install instructions in INSTALL.md
Just run and open http://localhost:4000/ Just run and open http://localhost:4000/
docker-compose -f docker-compose.dev.yml up` docker-compose -f docker-compose.yml up`
## Tips ## Tips
@ -22,6 +22,57 @@ and it still fails a bit. https://github.com/connorshea/vscode-ruby-test-adapter
1. Do not commit too much without testing. Also keep commits small for documentation and reversability issues. 1. Do not commit too much without testing. Also keep commits small for documentation and reversability issues.
1. You need to rebuild the docker image when you change gems. 1. You need to rebuild the docker image when you change gems.
## TODO issues for dev
1. Puma should be running (eg. spring), and if debugger is used it should be able to connect via docker-compose up
1. Should directories exist?
# Tags in code
FIXME, TODO, EXPLAIN, OBSOLETE
## Handy commands
Load env variables:
export $(cat .env.development | xargs) && export $(cat .env | xargs)
Start:
docker-compose -f docker-compose.yml up -d --build`
Build or rebuild:
docker-compose -f docker-compose.yml build`
Debug:
docker attach ensl_dev
To get inside docker web+test containers:
docker-compose -f docker-compose.yml exec -u root web /bin/bash`
docker-compose -f docker-compose.yml exec -u web web /bin/bash`
docker-compose -f docker-compose.yml exec -u root test /bin/bash`
docker-compose -f docker-compose.yml exec -u web test /bin/bash`
Restart the web container
docker-compose -f docker-compose.yml restart web`
Run some tests:
docker-compose -f docker-compose.yml exec -u web test bundle exec rspec`
docker-compose -f docker-compose.yml exec -u web test bundle exec rspec spec/controllers/shoutmsgs_controller_spec.rb`
# Design of ENSL Application
Read this to understand design decisions and follow them!
1. Env variables should be used everywhere and loaded from .env* files using Dotenv
1. The app contents are added to the docker image on build but it is mounted as **volume**.
1. Use rails / ruby best practices in section below.
## Best practices ## Best practices
1. https://nvie.com/posts/a-successful-git-branching-model/ 1. https://nvie.com/posts/a-successful-git-branching-model/
@ -30,41 +81,3 @@ and it still fails a bit. https://github.com/connorshea/vscode-ruby-test-adapter
1. http://www.betterspecs.org/ 1. http://www.betterspecs.org/
1. https://github.com/rubocop-hq/rspec-style-guide 1. https://github.com/rubocop-hq/rspec-style-guide
1. Run rubocop 1. Run rubocop
## TODO issues for dev
1. Puma should be running (eg. spring), and if debugger is used it should be able to connect via docker-compose up
# Tags in code
FIXME, TODO, EXPLAIN, OBSOLETE
## Handy commands
Start:
docker-compose -f docker-compose.dev.yml up -d --build`
Build or rebuild:
docker-compose -f docker-compose.dev.yml build`
Debug:
docker attach ensl_dev
To get inside docker web+test containers:
docker-compose -f docker-compose.dev.yml exec -u root web /bin/bash`
docker-compose -f docker-compose.dev.yml exec -u web web /bin/bash`
docker-compose -f docker-compose.dev.yml exec -u root test /bin/bash`
docker-compose -f docker-compose.dev.yml exec -u web test /bin/bash`
Restart the web container
docker-compose -f docker-compose.dev.yml restart web`
Run some tests:
docker-compose -f docker-compose.dev.yml exec -u web test bundle exec rspec`
docker-compose -f docker-compose.dev.yml exec -u web test bundle exec rspec spec/controllers/shoutmsgs_controller_spec.rb`

View file

@ -1,11 +1,9 @@
FROM ruby:2.6.5 FROM ruby:2.6.5 AS ensl_development
ENV RAILS_ENV production ENV RAILS_ENV development
# Add 'web' user which will run the application RUN adduser web --home /home/web --shell /bin/bash --disabled-password --gecos "" && \
RUN adduser web --home /home/web --shell /bin/bash --disabled-password --gecos "" apt-get update && apt-get -y upgrade \
RUN apt-get update && apt-get -y upgrade \
&& apt-get -y install \ && apt-get -y install \
libmariadb-dev libmariadb-dev-compat \ libmariadb-dev libmariadb-dev-compat \
libssl-dev \ libssl-dev \
@ -20,19 +18,48 @@ RUN apt-get update && apt-get -y upgrade \
ADD Gemfile Gemfile.lock /var/www/ ADD Gemfile Gemfile.lock /var/www/
RUN gem install bundler && \ RUN gem install bundler && \
mkdir -p /var/bundle && chown -R web:web /var/bundle && chown -R web:web /var/www mkdir -p /var/bundle && chown -R web:web /var/bundle && \
chown -R web:web /var/www
WORKDIR /var/www WORKDIR /var/www
USER web USER web
RUN bundle config github.https true && \ RUN bundle config github.https true && \
bundle config set path '/var/bundle' && \ bundle config set path '/var/bundle' && \
bundle install --jobs 8 && \ bundle install --jobs 8
bundle exec rake assets:precompile
USER root USER root
# Temporary fix for assets # ENTRYPOINT ["/bin/bash"]
RUN mv /var/www/public/assets /home/web/assets # CMD ["/var/www/bin/script/entry.sh"]
# Staging
FROM ensl_development AS ensl_staging
ENV RAILS_ENV staging
USER root
ENTRYPOINT ["/bin/bash"]
CMD ["/var/www/bin/script/entry.sh"]
# Production
FROM ensl_development AS ensl_production
ENV RAILS_ENV production
ADD . /var/www
WORKDIR /var/www
RUN chown -R web:web /var/www
USER web
RUN bundle exec rake assets:precompile && \
# Temporary fix for assets
mv /var/www/public/assets /home/web/assets
ENTRYPOINT ["/bin/bash"]
CMD ["/var/www/bin/script/entry.sh"] CMD ["/var/www/bin/script/entry.sh"]

View file

@ -1,32 +0,0 @@
FROM ruby:2.6.5
ENV RAILS_ENV development
# Add 'web' user which will run the application
RUN adduser web --home /home/web --shell /bin/bash --disabled-password --gecos ""
RUN apt-get update && apt-get -y upgrade \
&& apt-get -y install \
libmariadb-dev libmariadb-dev-compat \
libssl-dev \
zlib1g-dev libreadline-dev libyaml-dev \
libxslt1-dev libxml2-dev \
imagemagick libmagickwand-dev \
nodejs \
phantomjs \
firefox-esr
# Separate Gemfile ADD so that `bundle install` can be cached more effectively
ADD Gemfile Gemfile.lock /var/www/
RUN gem install bundler && \
mkdir -p /var/bundle && chown -R web:web /var/bundle && chown -R web:web /var/www
WORKDIR /var/www
USER web
RUN bundle config github.https true && \
bundle config set path '/var/bundle' && \
bundle install --jobs 8
CMD ["/var/www/bin/script/entry.sh"]

View file

@ -41,7 +41,7 @@ a) Then start for **production**:
b) ... or start for **development**: b) ... or start for **development**:
docker-compose -f docker-compose.dev.yml up docker-compose -f docker-compose.yml up
## 3. Install reverse proxy (production only) ## 3. Install reverse proxy (production only)

View file

@ -2,7 +2,7 @@
cd /var/www cd /var/www
source /var/www/.env source script/env.sh .env .env.$RAILS_ENV .env.$RAILS_ENV.local .env.local
if [ $RAILS_ENV = "production" ]; then if [ $RAILS_ENV = "production" ]; then
rm -rf /var/www/public/assets rm -rf /var/www/public/assets

View file

@ -24,6 +24,7 @@ module Ensl
config.autoload_paths += Dir["#{config.root}/app/services/**/", "#{config.root}/app/models/concerns/"] config.autoload_paths += Dir["#{config.root}/app/services/**/", "#{config.root}/app/models/concerns/"]
# Load secrets from .env # Load secrets from .env
ENV['APP_SECRET'] ||= (0...32).map { (65 + rand(26)).chr }.join
config.secret_token = ENV['APP_SECRET'] config.secret_token = ENV['APP_SECRET']
# Use cookies # Use cookies

View file

@ -3,7 +3,7 @@ base: &db
encoding: utf8 encoding: utf8
host: <%= ENV['MYSQL_HOST'] %> host: <%= ENV['MYSQL_HOST'] %>
database: <%= ENV['MYSQL_DATABASE'] %> database: <%= ENV['MYSQL_DATABASE'] %>
username: <%= ENV['MYSQL_USERNAME'] %> username: <%= ENV['MYSQL_USER'] %>
password: <%= ENV['MYSQL_PASSWORD'] %> password: <%= ENV['MYSQL_PASSWORD'] %>
pool: <%= Integer(ENV['MYSQL_CONNECTION_POOL'] || 8) %> pool: <%= Integer(ENV['MYSQL_CONNECTION_POOL'] || 8) %>
wait_timeout: 90 wait_timeout: 90

View file

@ -59,7 +59,7 @@ Ensl::Application.configure do
config.action_mailer.raise_delivery_errors = true config.action_mailer.raise_delivery_errors = true
# Enable threaded mode # Enable threaded mode
config.threadsafe! # config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found) # the I18n.default_locale when a translation can not be found)

View file

@ -9,10 +9,11 @@ Ensl::Application.configure do
config.action_controller.perform_caching = true config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this) # Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false config.serve_static_assets = true
# Compress JavaScripts and CSS # Compress JavaScripts and CSS
config.assets.compress = true config.assets.compress = true
config.assets.js_compressor = :uglifier
# Don't fallback to assets pipeline if a precompiled asset is missed # Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = true config.assets.compile = true
@ -51,9 +52,10 @@ Ensl::Application.configure do
# Use sendmail # Use sendmail
config.action_mailer.delivery_method = :sendmail config.action_mailer.delivery_method = :sendmail
config.action_mailer.raise_delivery_errors = true config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
# Enable threaded mode address: 'smtp',
config.threadsafe! domain: 'ensl.org'
}
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found) # the I18n.default_locale when a translation can not be found)
@ -63,7 +65,7 @@ Ensl::Application.configure do
config.active_support.deprecation = :notify config.active_support.deprecation = :notify
# Custom Session Store config to allow gathers.staging.ensl.org # Custom Session Store config to allow gathers.staging.ensl.org
config.session_store :cookie_store, key: "_ENSL_session_key_staging", expire_after: 30.days.to_i, domain: ".staging.ensl.org" config.session_store :cookie_store, key: "_ENSL_session_key_staging", expire_after: 30.days.to_i
config.eager_load = true config.eager_load = true
end end

View file

@ -1,7 +1,7 @@
# Load dev vars # Load dev vars
# FIXME: right dev file is not loaded # FIXME: right dev file is not loaded
require "dotenv" require "dotenv"
Dotenv.load() Dotenv.load(".env.local", '.env' + ENV['RAILS_ENV'] + '.local', '.env' + ENV['RAILS_ENV'], '.env')
tag 'ENSL' tag 'ENSL'

View file

@ -1,111 +0,0 @@
version: "3"
services:
web:
command: "bundle exec puma"
tty: true
stdin_open: true
# NOtE: Use attach rather than this
# Debug
# command: /bin/bash
container_name: ensl_dev
build:
context: ./
dockerfile: Dockerfile.dev
# args:
# buildno: 1
volumes:
- ".:/var/www/"
ports:
- "4000:4000"
- "35729:35729"
links:
- db
- memcached
#- spring
#- selenium
#- redis
test:
# Debug
#stdin_open: true
command: ["/bin/bash", "-c", "--", "while true; do sleep 100; done;"]
container_name: ensl_test
build:
context: ./
dockerfile: Dockerfile.dev
args:
buildno: 1
env_file:
- .env.test
ports:
- 3005:3005 # Capybara listens here
links:
- db
# - selenium
volumes:
- ".:/var/www"
# command: bin/spring server
environment:
TEST_APP_HOST: test
TEST_APP_PORT: 3005
SELENIUM_HOST: selenium
RAILS_ENV: test
networks:
default:
aliases:
- test
redis:
image: 'redis:4.0-alpine'
container_name: ensl_dev_redis
selenium:
image: selenium/standalone-chrome-debug
container_name: ensl_dev_selenium
ports:
- 5900:5900
- 4444:4444
# spring:
# build:
# context: ./
# dockerfile: Dockerfile.dev
# args:
# buildno: 1
# volumes:
# - .:/var/www
# command: spring server
# This ensures that the pid namespace is shared between the host
# and the container. It's not necessary to be able to run spring
# commands, but it is necessary for "spring status" and "spring stop"
# to work properly.
# pid: host
db:
# Debug
#command: bash
#tty: true
# command: mysqld_safe --skip-grant-tables
image: mariadb:latest
container_name: ensl_dev_db
user: "mysql:mysql"
volumes:
- "./db/data:/var/lib/mysql"
- "./db/initdb.d:/docker-entrypoint-initdb.d"
- "./ext/mysql.conf.d:/etc/mysql/conf.d"
environment:
- MYSQL_DATABASE=ensl
- MYSQL_USER=ensl
- MYSQL_USERNAME=ensl
- MYSQL_PASSWORD=ensl
- MYSQL_ROOT_PASSWORD=ensl
- MYSQL_ROOT_HOST=%
memcached:
image: memcached:latest
container_name: ensl_dev_memcached
#redis:
# image: redis

View file

@ -1,40 +1,140 @@
version: "3" version: "3.4"
services: services:
#
# Main service
#
web: web:
image: ensl/ensl.org:latest # For debug; Use attach rather than this
# command: /bin/bash
command: "bundle exec puma"
tty: true
stdin_open: true
container_name: "ensl_${RAILS_ENV}"
user: "web:web"
build:
context: ./
dockerfile: Dockerfile
target: ensl_${RAILS_ENV}
volumes: volumes:
- "../public:/var/www/public" - ".:/var/www/"
- "../logs:/var/www/log" environment:
RAILS_ENV: $RAILS_ENV
ports: ports:
- "4000:4000" - "${PUMA_PORT}:${PUMA_PORT}"
depends_on: - "35729:35729"
links:
- db - db
- memcached - memcached
- smtp - smtp
#- spring
#- redis #- redis
#
# Testing
#
# Seperate test container so dev / test don't cause problems
test:
command: ["bash", "-c", "while true; do sleep 100; done;"]
container_name: ensl_test
build:
context: ./
dockerfile: Dockerfile
target: ensl_development
env_file:
- .env.test
ports:
- ${TEST_APP_PORT}:${TEST_APP_PORT} # Capybara listens here
links:
- db
- memcached
- selenium
volumes:
- ".:/var/www"
# command: bin/spring server
environment:
RAILS_ENV: test
networks:
default:
aliases:
- test
selenium:
image: selenium/standalone-chrome-debug
container_name: ensl_${RAILS_ENV}_selenium
ports:
- 5900:5900
- 4444:4444
#
# Common services: These are shared by all envs.
#
memcached:
image: memcached:alpine
container_name: ensl_${RAILS_ENV}_memcached
redis:
image: 'redis:4.0-alpine'
container_name: ensl_${RAILS_ENV}_redis
db: db:
image: mariadb:latest image: mariadb:latest
command: mysqld container_name: ensl_${RAILS_ENV}_db
user: "mysql:mysql"
# debug; command: mysqld_safe --skip-grant-tables
volumes: volumes:
- "./db_data:/var/lib/mysql" - "./db/data:/var/lib/mysql"
- "./db/initdb.d:/docker-entrypoint-initdb.d"
- "./ext/mysql.conf.d:/etc/mysql/conf.d" - "./ext/mysql.conf.d:/etc/mysql/conf.d"
environment: environment:
- MYSQL_DATABASE - MYSQL_DATABASE=$MYSQL_DATABASE
- MYSQL_USER - MYSQL_USER=$MYSQL_USER
- MYSQL_USERNAME - MYSQL_PASSWORD=$MYSQL_PASSWORD
- MYSQL_PASSWORD - MYSQL_ROOT_PASSWORD=$MYSQL_PASSWORD
- MYSQL_ROOT_PASSWORD - MYSQL_ROOT_HOST=$MYSQL_ROOT_HOST
# - MYSQL_ROOT_HOST
memcached:
image: memcached:latest
smtp: smtp:
image: mwader/postfix-relay:latest image: mwader/postfix-relay:latest
container_name: ensl_${RAILS_ENV}_smtp
restart: always restart: always
volumes: volumes:
- "../dkim:/etc/opendkim/keys" - "./ext/dkim:/etc/opendkim/keys"
environment: environment:
- POSTFIX_myhostname=ensl.org - POSTFIX_myhostname=$APP_DOMAIN
- OPENDKIM_DOMAINS=ensl.org - OPENDKIM_DOMAINS=$APP_DOMAIN
#redis:
# image: redis nginx:
image: nginx:latest
command: /bin/bash
container_name: ensl_${RAILS_ENV}_nginx
volumes:
- ./ext/ssl/fullchain.pem:/etc/ssl/certs/ensl_fullchain.pem
- ./ext/ssl/privkey.pem:/etc/ssl/private/ensl_privkey.pem
- ./ext/nginx.conf.d/:/etc/nginx/conf.d/
- ./public:/var/www
ports:
- $APP_PORT:80
- $APP_PORT_SSL:443
environment:
- APP_DOMAIN=$APP_DOMAIN
- APP_PORT=$APP_PORT
- PUMA_PORT=$PUMA_PORT
- RAILS_ENV=$RAILS_ENV
# command: /bin/bash -c "envsubst '$$PUMA_PORT' < /etc/nginx/conf.d/nginx.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
# spring:
# build:
# context: ./
# dockerfile: Dockerfile.dev
# args:
# buildno: 1
# volumes:
# - .:/var/www
# command: spring server
# This ensures that the pid namespace is shared between the host
# and the container. It's not necessary to be able to run spring
# commands, but it is necessary for "spring status" and "spring stop"
# to work properly.
# pid: host

View file

@ -1,119 +0,0 @@
upstream puma {
# server unix:/srv/ensl/puma.production.sock fail_timeout=0;
server localhost:4000;
}
server {
listen *:80;
listen *:443 ssl;
ssl_certificate /etc/letsencrypt/live/ensl.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ensl.org/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name ensl.org;
root /srv/ensl/root_domain;
return 301 https://www.ensl.org$request_uri;
}
server {
listen *:80;
server_name www.ensl.org;
return 301 https://www.ensl.org$request_uri;
}
server {
listen *:443 ssl default_server;
server_name www.ensl.org;
root /srv/ensl/public;
index index.html index.htm index.php;
ssl_certificate /etc/letsencrypt/live/ensl.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ensl.org/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
#add_header Strict-Transport-Security max-age=15768000;
access_log /var/log/nginx/ensl.access.log;
error_log /var/log/nginx/ensl.error.log;
rewrite_log on;
client_max_body_size 20M;
keepalive_timeout 10;
location ~ /.well-known {
allow all;
autoindex on;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /files/ {
try_files $uri $uri/ @puma;
alias /srv/ensl/files/;
autoindex on;
}
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://puma;
}
try_files $uri/index.html $uri @puma;
}
upstream puma_staging {
server localhost:5000;
}
server {
listen *:5000 ssl;
server_name www.ensl.org;
root /srv/ensl.org.staging/public;
index index.html index.htm index.php;
auth_basic “ENSL Staging area”;
auth_basic_user_file /etc/nginx/.htpasswd;
ssl_certificate /etc/letsencrypt/live/ensl.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ensl.org/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
#add_header Strict-Transport-Security max-age=15768000;
#access_log /var/log/nginx/ensl.access.log;
#error_log /var/log/nginx/ensl.error.log;
rewrite_log on;
client_max_body_size 20M;
keepalive_timeout 10;
location ~ /.well-known {
allow all;
autoindex on;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /files/ {
try_files $uri $uri/ @puma_staging;
alias /srv/ensl/files/;
autoindex on;
}
location @puma_staging {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://puma_staging;
}
try_files $uri/index.html $uri @puma_staging;
}

View file

@ -0,0 +1,75 @@
# Staging nginx conf
# The point of this config file is to have near-identical setup in staging.
# Use it in production or copy it over
upstream puma {
server localhost:$PUMA_PORT;
# server unix:/var/tmp/puma.$RAILS_ENV.sock fail_timeout=0;
}
# root-level -> www redirect
server {
listen *:80;
listen *:443 ssl;
ssl_certificate /etc/ssl/certs/ensl_fullchain.pem;
ssl_certificate_key /etc/ssl/private/ensl_privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name ensl.org;
root /var/www;
return 301 https://www.ensl.org$request_uri;
}
# HTTP -> HTTPS redirect
server {
listen *:80;
server_name www.ensl.org;
return 301 https://www.ensl.org$request_uri;
}
server {
listen *:443 ssl default_server;
server_name www.ensl.org;
root /var/www;
index index.html index.htm index.php;
ssl_certificate /etc/ssl/certs/ensl_fullchain.pem;
ssl_certificate_key /etc/ssl/private/ensl_privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
#add_header Strict-Transport-Security max-age=15768000;
access_log /var/log/nginx/ensl.access.log;
error_log /var/log/nginx/ensl.error.log;
rewrite_log on;
client_max_body_size 20M;
keepalive_timeout 10;
location ~ /.well-known {
allow all;
autoindex on;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /files/ {
# try_files $uri $uri/ @puma;
# alias root /var/www/files/;
autoindex on;
}
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://puma;
}
try_files $uri/index.html $uri @puma;
}

18
script/env.sh Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
# use source script/env.sh
args=("$@")
if [[ $# -eq 1 ]]; then
args+=(.env)
fi
for FILE in "$@"
do
echo "Loading env vars from: $FILE"
ARGS=$(cat $FILE |grep -vE '^[[:space:]]*(#.*)*$')
export $(echo $ARGS|xargs)
echo "$ARGS\n"
done

View file

@ -1,7 +1,6 @@
ENV["RAILS_ENV"] ||= "test" ENV["RAILS_ENV"] ||= "test"
require 'dotenv' require 'dotenv/load'
Dotenv.load()
require "codeclimate-test-reporter" require "codeclimate-test-reporter"
require "simplecov" require "simplecov"