From dc726fdbe04885f159850529d3f839537408c4b4 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 29 Jul 2019 15:15:23 -0300 Subject: [PATCH] deploy en docker --- .env.example | 1 + .gitignore | 4 ++-- Dockerfile | 31 ++++++++++++++++++++++--------- bin/rails | 35 ++++++++++++++++++++++++++++------- bin/sidekiq | 32 ++++++++++++++++++++++++++++++++ bin/sidekiqctl | 32 ++++++++++++++++++++++++++++++++ config/database.yml | 2 +- monit.conf | 4 ++++ sync_assets.sh | 5 +++++ 9 files changed, 127 insertions(+), 19 deletions(-) create mode 100755 bin/sidekiq create mode 100755 bin/sidekiqctl create mode 100644 sync_assets.sh diff --git a/.env.example b/.env.example index 70475f6..0a8c05d 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ +RAILS_ENV=production SECRET_KEY_BASE= IMAP_SERVER= DEFAULT_FROM= diff --git a/.gitignore b/.gitignore index 483c916..5cf7616 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,6 @@ /_sites/* /_deploy/* -/_usuarias/* -/_invitadxs/* +/data/* + .env diff --git a/Dockerfile b/Dockerfile index faa5672..ddf957c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ENV SECRET_KEY_BASE solo_es_necesaria_para_correr_rake ENV RAILS_ENV production # Para compilar los assets en brotli -RUN apk add --no-cache brotli +RUN apk add --no-cache brotli libgit2-dev rsync cmake # Empezamos con la usuaria app creada por sdk-ruby USER app @@ -21,10 +21,16 @@ WORKDIR /home/app/sutty # Copiamos solo el Gemfile para poder instalar las gemas necesarias COPY --chown=app:www-data ./Gemfile . COPY --chown=app:www-data ./Gemfile.lock . -# Instalar las gemas de producción +# XXX: Esto va a tener permisos de 1000, idealmente el usuario que lanza +# la compilación +RUN rsync -a 172.17.0.1::ccache/ /home/app/.ccache/ +# Instalar las gemas de producción usando ccache para no recompilar +# gemas nativas # XXX: No usamos la flag --production porque luego no nos deja # desinstalar las gemas de los assets -RUN bundle install --path=./vendor --without test development +# RUN --mount=type=cache,target=/home/app/.ccache \ +RUN if ! bundle install --path=./vendor --without test development ; then rsync -a /home/app/.ccache/ 172.17.0.1::ccache/ ; exit 1 ; fi +RUN rsync -a /home/app/.ccache/ 172.17.0.1::ccache/ # Vaciar la caché RUN rm vendor/ruby/2.5.0/cache/*.gem # Limpiar las librerías nativas, esto ahorra más espacio y uso de @@ -37,7 +43,7 @@ COPY --chown=app:www-data ./.git/ ./.git/ RUN git archive -o ../sutty.tar.gz HEAD # Extraer archivos necesarios para compilar los assets -RUN tar xvf ../sutty.tar.gz Rakefile config app yarn.lock package.json +RUN tar xf ../sutty.tar.gz Rakefile config app yarn.lock package.json # Instalar los paquetes JS RUN yarn # Pre-compilar los assets @@ -50,8 +56,10 @@ RUN find public/assets -type f | grep -v ".gz$" | xargs -r brotli -k -9 RUN sed -re "/(uglifier|bootstrap|coffee-rails)/d" -i Gemfile RUN bundle clean + # Contenedor final FROM sutty/monit:latest +ENV RAILS_ENV production # Instalar las dependencias, separamos la librería de base de datos para # poder reutilizar este primer paso desde otros contenedores @@ -61,8 +69,9 @@ RUN apk add --no-cache sqlite-libs # XXX: Eliminarlo cuando extraigamos la generación de sitios del proceso # principal RUN apk add --no-cache yarn +RUN apk add --no-cache libgit2 # Instalar foreman para poder correr los servicios -RUN gem install --no-rdoc --no-ri --no-user-install foreman +RUN gem install --no-document --no-user-install foreman # Agregar el grupo del servidor web RUN addgroup -g 82 -S www-data @@ -80,9 +89,9 @@ COPY --from=build --chown=app:www-data /home/app/sutty.tar.gz /tmp/ RUN tar xf /tmp/sutty.tar.gz && rm /tmp/sutty.tar.gz # Traer los assets compilados y las gemas -COPY --from=build --chown=app:www-data /home/app/web/public/assets public/assets -COPY --from=build --chown=app:www-data /home/app/web/vendor vendor -COPY --from=build --chown=app:www-data /home/app/web/.bundle .bundle +COPY --from=build --chown=app:www-data /home/app/sutty/public/assets public/assets +COPY --from=build --chown=app:www-data /home/app/sutty/vendor vendor +COPY --from=build --chown=app:www-data /home/app/sutty/.bundle .bundle # Volver a root para cerrar la compilación USER root @@ -90,11 +99,15 @@ USER root # Instalar la configuración de monit y comprobarla RUN install -m 640 -o root -g root ./monit.conf /etc/monit.d/sutty.conf RUN monit -t +# Sincronizar los assets a un directorio compartido +RUN apk add --no-cache rsync +COPY ./sync_assets.sh /usr/local/bin/sync_assets +RUN chmod 755 /usr/local/bin/sync_assets # Mantener estos directorios! VOLUME "/srv/http/_deploy" VOLUME "/srv/http/_sites" -VOLUME "/srv/http/public" +VOLUME "/srv/http/_public" # El puerto de puma EXPOSE 3000 diff --git a/bin/rails b/bin/rails index 3504c3f..088d75d 100755 --- a/bin/rails +++ b/bin/rails @@ -1,11 +1,32 @@ #!/usr/bin/env ruby # frozen_string_literal: true -begin - load File.expand_path('spring', __dir__) -rescue LoadError => e - raise unless e.message.include?('spring') +# +# This file was generated by Bundler. +# +# The application 'rails' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path('bundle', __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort( + 'Your `bin/bundle` was not generated by Bundler, so this binstub + cannot run. Replace `bin/bundle` by running `bundle binstubs + bundler --force`, then run this command again.' + ) + end end -APP_PATH = File.expand_path('../config/application', __dir__) -require_relative '../config/boot' -require 'rails/commands' + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('railties', 'rails') diff --git a/bin/sidekiq b/bin/sidekiq new file mode 100755 index 0000000..5d97d88 --- /dev/null +++ b/bin/sidekiq @@ -0,0 +1,32 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'sidekiq' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path('bundle', __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort( + 'Your `bin/bundle` was not generated by Bundler, so this binstub + cannot run. Replace `bin/bundle` by running `bundle binstubs + bundler --force`, then run this command again.' + ) + end +end + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sidekiq', 'sidekiq') diff --git a/bin/sidekiqctl b/bin/sidekiqctl new file mode 100755 index 0000000..10eb2f4 --- /dev/null +++ b/bin/sidekiqctl @@ -0,0 +1,32 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'sidekiqctl' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path('bundle', __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort( + 'Your `bin/bundle` was not generated by Bundler, so this binstub + cannot run. Replace `bin/bundle` by running `bundle binstubs + bundler --force`, then run this command again.' + ) + end +end + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sidekiq', 'sidekiqctl') diff --git a/config/database.yml b/config/database.yml index 0d02f24..f7a3238 100644 --- a/config/database.yml +++ b/config/database.yml @@ -22,4 +22,4 @@ test: production: <<: *default - database: db/production.sqlite3 + database: data/production.sqlite3 diff --git a/monit.conf b/monit.conf index 211b03a..4d34d69 100644 --- a/monit.conf +++ b/monit.conf @@ -1,3 +1,7 @@ check process sutty with pidfile /srv/http/tmp/puma.pid start program = "/bin/sh -c 'cd /srv/http && foreman start migrate && foreman start sutty'" as uid app stop program = "/bin/sh -c 'cat /srv/http/tmp/puma.pid | xargs kill'" + +check program sync_assets + with path /usr/local/bin/sync_assets + if status = 0 then unmonitor diff --git a/sync_assets.sh b/sync_assets.sh new file mode 100644 index 0000000..167d620 --- /dev/null +++ b/sync_assets.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# Sincronizar assets desde public a _public para que estén disponibles +# en el contenedor web. + +rsync -a --delete-after public/ _public/