-
-
Save marcometz/ddee699779d38ac01de9ec05b4cbb066 to your computer and use it in GitHub Desktop.
New Rails App with Docker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DOMAIN=docker.localhost | |
PRODUCTION_DOMAIN=foo.bar.de | |
APP=appname-api | |
REGISTRY_URL=registry.foo.bar.de/tpwd/appname-api | |
NODE_ENV=development |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem "whenever", require: false | |
gem "unicorn" | |
gem "rswag-api" | |
gem "rswag-ui" | |
gem_group :development, :test do | |
gem "byebug", platforms: %i[mri mingw x64_mingw] | |
gem "pry-rails" | |
gem "rails-controller-testing" | |
gem "rspec-rails" | |
gem "rswag-specs" | |
gem "rspec_junit_formatter" | |
gem "simplecov", "0.17.1", require: false | |
gem "simplecov-json", require: false, git: "https://github.com/kevjin/simplecov-json.git", branch: "simplecov-compatibility" | |
end | |
gem_group :development do | |
gem "annotate" | |
gem "rubocop", "~> 0.81.0", require: false | |
gem "rubocop-rspec" | |
# Access an interactive console on exception pages or by calling 'console' anywhere in the code. | |
gem "web-console", ">= 3.3.0" | |
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring | |
gem "spring" | |
gem "spring-watcher-listen", "~> 2.0.0" | |
end | |
gem_group :test do | |
gem "capybara" | |
gem "database_cleaner" | |
gem "factory_bot_rails" | |
gem "faker" | |
gem "selenium-webdriver" | |
gem "shoulda" | |
gem "timecop" | |
gem "vcr" | |
gem "webdrivers" | |
gem "webmock" | |
end | |
# | |
# CronJob Config File | |
# | |
schedule_config = <<-EOL | |
# Use this file to easily define all of your cron jobs. | |
# | |
# It's helpful, but not entirely necessary to understand cron before proceeding. | |
# http://en.wikipedia.org/wiki/Cron | |
# Example: | |
# | |
# set :output, "/path/to/my/cron_log.log" | |
# | |
# every 2.hours do | |
# command "/usr/bin/some_great_command" | |
# runner "MyModel.some_method" | |
# rake "some:great:rake:task" | |
# end | |
# | |
# every 4.days do | |
# runner "AnotherModel.prune_old_records" | |
# end | |
set :job_template, "/bin/sh -l -c ':job'" | |
set :environment, ENV["RAILS_ENV"] | |
EOL | |
create_file "config/schedule.rb", schedule_config | |
# | |
# Quantum Settings File | |
# | |
quantum = <<-EOL | |
--- | |
version: '1.0' | |
compose: quantum.yml | |
EOL | |
create_file ".quantum", quantum | |
# | |
# Database Config | |
# | |
database_config = <<-EOL | |
default: &default | |
adapter: postgresql | |
encoding: unicode | |
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> | |
host: postgres | |
username: postdb | |
password: postdb | |
development: | |
<<: *default | |
database: postdb | |
test: | |
<<: *default | |
database: postdb_test | |
production: | |
<<: *default | |
database: postdb | |
host: postgres | |
username: postdb | |
password: postdb | |
EOL | |
create_file "config/database.yml.tmpl", database_config, force: true | |
run "bundle install" | |
run "bundle exec rails webpacker:install" | |
# | |
# Entrypoint Dockerfile | |
# | |
entrypoint = <<-EOL | |
#!/bin/sh | |
set -e | |
dockerize -wait tcp://postgres:5432 -timeout 30s | |
if [ $RAILS_ENV == development ]; then | |
bundle check || bundle install --binstubs="$BUNDLE_BIN" --with development | |
else | |
bundle check || bundle install --binstubs="$BUNDLE_BIN" | |
fi | |
# bundle exec rails webpacker:install | |
# yarn install --check-files | |
bundle exec rake assets:precompile | |
bundle exec rake db:create db:migrate | |
rm -f /unicorn.pid | |
exec "$@" | |
EOL | |
create_file "docker/entrypoint.sh", entrypoint | |
chmod "docker/entrypoint.sh", "+x" | |
# | |
# CronJob Startscript | |
# | |
start_cron = <<-EOL | |
#!/bin/sh | |
bundle exec whenever --write-crontab | |
crond -f | |
EOL | |
create_file "bin/start-cron.sh", start_cron | |
chmod "bin/start-cron.sh", "+x" | |
# | |
# Unicorn configuration | |
# | |
unicorn_config = <<-EOL | |
app_dir = "/app" | |
worker_processes ENV.fetch("UNICORN_WORKER") { 2 } | |
working_directory app_dir | |
# Load app into the master before forking workers for super-fast | |
# worker spawn times | |
preload_app true | |
# nuke workers after 60 seconds (the default) | |
timeout 60 | |
# listen on a Unix domain socket and/or a TCP port, | |
listen "/unicorn/socket" | |
pid "/unicorn.pid" | |
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow | |
if GC.respond_to?(:copy_on_write_friendly=) | |
GC.copy_on_write_friendly = true | |
end | |
after_fork do |server, worker| | |
# Unicorn master loads the app then forks off workers - because of the way | |
# Unix forking works, we need to make sure we aren't using any of the parent's | |
# sockets, e.g. db connection | |
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection | |
# Redis and Memcached would go here but their connections are established | |
# on demand, so the master never opens a socket | |
end | |
EOL | |
create_file "config/unicorn.rb", unicorn_config | |
# | |
# NginxConfig : testen ob es entfernt werden kann | |
# | |
nginx_conf = <<-EOL | |
upstream app { | |
server unix:/unicorn/socket fail_timeout=0; | |
} | |
server { | |
listen 80; | |
server_name localhost; | |
root /app/public; | |
try_files $uri/index.html $uri @app; | |
location @app { | |
proxy_pass http://app; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_set_header X-Forwarded-Proto $scheme; | |
proxy_set_header Host $http_host; | |
proxy_redirect off; | |
} | |
location ^~ /uploads/ { | |
access_log off; | |
gzip_static on; | |
expires max; | |
add_header Cache-Control public; | |
} | |
location ^~ /assets/ { | |
access_log off; | |
gzip_static on; | |
expires max; | |
add_header Cache-Control public; | |
} | |
client_max_body_size 4G; | |
keepalive_timeout 10; | |
} | |
EOL | |
create_file "docker/nginx.conf", nginx_conf | |
# | |
# Dockerfile | |
# | |
dockerfile = <<-EOL | |
FROM registry.gitlab.tpwd.de/cmmc-systems/ruby-nginx/ruby-2.7.1 | |
LABEL maintainer="Marco Metz <mm@tpwd.de>" | |
# Für RailsAdmin Importer | |
RUN apk add icu-dev | |
# Für Cronjobs | |
RUN apk add dcron | |
RUN mkdir -p /var/log/cron && mkdir -m 0644 -p /var/spool/cron/crontabs && touch /var/log/cron/cron.log && mkdir -m 0644 -p /etc/cron.d | |
# für DB Zugriffe aus der Console heraus | |
RUN apk add mysql-client | |
# minIO Client in der Console | |
RUN apk add wget | |
RUN wget https://dl.min.io/client/mc/release/linux-amd64/mc | |
RUN chmod +x mc | |
RUN mv mc /bin | |
RUN mkdir -p /unicorn | |
RUN mkdir -p /app | |
WORKDIR /app | |
COPY . . | |
COPY config/database.yml.tmpl config/database.yml | |
ENTRYPOINT ["/app/docker/entrypoint.sh"] | |
CMD ["sh", "-c", "nginx-debug ; bundle exec unicorn -c config/unicorn.rb"] | |
EOL | |
create_file "Dockerfile", dockerfile | |
# | |
# Docker Compose | |
# | |
docker_compose = <<-EOL | |
version: '3.7' | |
services: | |
postgres: | |
image: 'postgres:10.3-alpine' | |
hostname: postgres | |
restart: unless-stopped | |
environment: | |
POSTGRES_USER: postdb | |
POSTGRES_PASSWORT: postdb | |
POSTGRES_DB: postdb | |
networks: | |
public: | |
adminer: | |
aliases: | |
- postgres | |
volumes: | |
- postgres:/var/lib/postgresql/data | |
app: | |
image: ${REGISTRY_URL}:latest | |
hostname: ${APP} | |
environment: | |
RAILS_ENV: production | |
RAILS_LOG_TO_STDOUT: 1 | |
container_name: ${APP} | |
restart: unless-stopped | |
depends_on: | |
- postgres | |
networks: | |
public: | |
aliases: | |
- ${APP} | |
volumes: | |
- bundle:/bundle | |
- assets:/app/public/assets | |
- node_modules:/app/node_modules | |
labels: | |
- traefik.enable=true | |
- traefik.docker.network=public | |
- traefik.frontend.errors.network.backend=error | |
- traefik.frontend.errors.network.query=/{status}.html | |
- traefik.frontend.errors.network.status=500-511 | |
configs: | |
- source: master-key | |
target: /app/config/master.key | |
- source: production-key | |
target: /app/config/production.key | |
cron: | |
image: ${REGISTRY_URL}:latest | |
environment: | |
RAILS_ENV: production | |
RAILS_LOG_TO_STDOUT: 1 | |
restart: unless-stopped | |
entrypoint: sh | |
command: bin/start-cron.sh | |
depends_on: | |
- postgres | |
configs: | |
- source: master-key | |
target: /app/config/master.key | |
- source: production-key | |
target: /app/config/production.key | |
networks: | |
public: | |
aliases: | |
- ${APP} | |
volumes: | |
- bundle:/bundle | |
- assets:/app/public/assets | |
- node_modules:/app/node_modules | |
volumes: | |
postgres: | |
assets: | |
bundle: | |
node_modules: | |
configs: | |
master-key: | |
external: true | |
production-key: | |
external: true | |
networks: | |
public: | |
external: true | |
adminer: | |
external: true | |
EOL | |
create_file "docker-compose.yml", docker_compose | |
# | |
# Docker Compose Overrride | |
# | |
docker_compose_override = <<-EOL | |
version: '3.7' | |
services: | |
app: | |
build: | |
context: . | |
dockerfile: Dockerfile | |
environment: | |
RAILS_ENV: development | |
ports: | |
- "3000:80" | |
volumes: | |
- .:/app:delegated | |
labels: | |
- traefik.enable=true | |
- traefik.docker.network=public | |
- traefik.frontend.rule=Host:${APP}.${DOMAIN} | |
EOL | |
create_file "docker-compose.override.yml", docker_compose_override | |
# | |
# Drone Config | |
# | |
drone_config = <<-EOL | |
--- | |
kind: pipeline | |
type: docker | |
name: Test, Build and Deploy | |
steps: | |
- name: Docker compose build quantum | |
image: docker/compose | |
settings: | |
username: | |
from_secret: REGISTRY_USER | |
password: | |
from_secret: REGISTRY_PASSWORD | |
registry: registry.gitlab.tpwd.de | |
repo: registry.gitlab.tpwd.de/tpwd/PLEASE_REPLACE_ME | |
dockerfile: Dockerfile | |
tags: | |
- latest | |
commands: | |
- docker-compose -f docker-compose.yml -f stack.yml config > quantum.yaml | |
volumes: | |
- name: quantum_yml | |
path: /quantum.yaml | |
- name: docker_socket | |
path: /var/run/docker.sock | |
when: | |
branch: | |
- master | |
depends_on: | |
- code-analysis | |
- name: Build and push Docker image | |
image: plugins/docker | |
settings: | |
username: | |
from_secret: REGISTRY_USER | |
password: | |
from_secret: REGISTRY_PASSWORD | |
registry: registry.gitlab.tpwd.de | |
repo: registry.gitlab.tpwd.de/tpwd/PLEASE_REPLACE_ME | |
dockerfile: Dockerfile | |
tags: | |
- latest | |
volumes: | |
- name: quantum_yml | |
path: /quantum.yaml | |
- name: docker_socket | |
path: /var/run/docker.sock | |
when: | |
branch: | |
- master | |
depends_on: | |
- Docker compose build quantum | |
- name: Deploy | |
image: registry.internal.planetary-networks.de/quantum-public/cli:2 | |
environment: | |
QUANTUM_USER: | |
from_secret: QUANTUM_USER | |
QUANTUM_PASSWORD: | |
from_secret: QUANTUM_PASSWORD | |
commands: | |
- quantum-cli stack update --create --wait --stack PLEASE_REPLACE_ME --endpoint PLEASE_REPLACE_ME --environment production | |
volumes: | |
- name: quantum_yml | |
path: /quantum.yaml | |
- name: docker_socket | |
path: /var/run/docker.sock | |
when: | |
branch: | |
- master | |
depends_on: | |
- Build and push Docker image | |
volumes: | |
- name: quantum_yml | |
temp: {} | |
- name: coverage | |
temp: {} | |
- name: docker_socket | |
host: | |
path: /var/run/docker.sock | |
EOL | |
create_file ".drone.yml", drone_config | |
# | |
# Stack Config | |
# | |
stack_config = <<-EOL | |
version: '3.7' | |
services: | |
app: | |
deploy: | |
labels: | |
traefik.enable: "true" | |
traefik.port: 80 | |
traefik.docker.network: public | |
traefik.main.frontend.rule: Host:api.${HOST} | |
traefik.main.frontend.passHostHeader: "true" | |
traefik.main.frontend.redirect.entryPoint: https | |
traefik.api.frontend.rule: Host:${PRODUCTION_DOMAIN} | |
traefik.api.frontend.passHostHeader: "true" | |
traefik.api.frontend.redirect.entryPoint: https | |
configs: | |
- source: master-key | |
target: /app/config/master.key | |
- source: production-key | |
target: /app/config/credentials/production.key | |
cron: | |
configs: | |
- source: master-key | |
target: /app/config/master.key | |
- source: production-key | |
target: /app/config/credentials/production.key | |
configs: | |
master-key: | |
external: true | |
production-key: | |
external: true | |
EOL | |
create_file "stack.yml", stack_config | |
# | |
# Starte Docker Server | |
# | |
run "docker-compose up --build" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--database=postgresql | |
--template=~/.rails_template.rb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment