diff --git a/.dockerignore b/.dockerignore index 3be14a38..67ab2daf 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,20 +1,20 @@ Dockerfile -node_modules/ -tmp/ -log/ -public/ -docs/ -bin/ -db/ -lib/ -test/ -tmp/ -vendor/ +node_modules +tmp +log +docs +bin +db +lib +test +tmp +vendor config.ru LICENSE Makefile monit.conf README.md TODO* -_deploy/ -_sites/ +_deploy +_sites +_storage diff --git a/.gitignore b/.gitignore index 15d27058..380b9840 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,10 @@ /public/packs /public/packs-test +/public/assets +/public/assets-production +/public/packs +/public/packs-production /node_modules /yarn-error.log yarn-debug.log* diff --git a/Dockerfile b/Dockerfile index 1d7f6e91..27262cce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,12 +2,7 @@ # el mismo repositorio de trabajo. Cuando tengamos CI/CD algunas cosas # como el tarball van a tener que cambiar porque ya vamos a haber hecho # un clone/pull limpio. -FROM sutty/oxipng:latest AS oxipng -FROM sutty/jemalloc:latest AS jemalloc -RUN echo /home/builder/packages/home > /etc/apk/repositories -RUN apk add --no-cache jemalloc - -FROM alpine:3.11.6 as build +FROM alpine:3.11.6 AS build MAINTAINER "f " ARG RAILS_MASTER_KEY @@ -31,7 +26,7 @@ RUN cd /usr/lib/ruby/2.6.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch RUN addgroup -g 82 -S www-data RUN adduser -s /bin/sh -G www-data -h /home/app -D app RUN install -dm750 -o app -g www-data /home/app/sutty -RUN gem install --no-document bundler:2.0.2 +RUN gem install --no-document bundler # Empezamos con la usuaria app USER app @@ -58,10 +53,9 @@ RUN mv ../sutty/.bundle ./.bundle # Instalar secretos COPY --chown=app:root ./config/credentials.yml.enc ./config/ -# Pre-compilar los assets -RUN bundle exec rake assets:precompile -# Comprimirlos usando brotli -RUN find public -type f -name "*.gz" | sed -re "s/\.gz$//" | xargs -r brotli -k -9 +# Traer los assets pre-compilados +COPY --chown=app:www-data ./public/assets-production ./public/assets +COPY --chown=app:www-data ./public/packs-production ./public/packs # Eliminar la necesidad de un runtime JS en producción, porque los # assets ya están pre-compilados. @@ -73,14 +67,14 @@ RUN rm -rf ./node_modules ./tmp/cache ./.git FROM sutty/monit:latest ENV RAILS_ENV production -# Instalar oxipng -COPY --from=oxipng --chown=root:root /root/.cargo/bin/oxipng /usr/bin/oxipng -RUN chmod 755 /usr/bin/oxipng +# Pandoc +RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories # Instalar las dependencias, separamos la librería de base de datos para # poder reutilizar este primer paso desde otros contenedores -RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-bundler ruby-json ruby-bigdecimal ruby-rake +RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-bundler ruby-json ruby-bigdecimal ruby-rake ruby-irb RUN apk add --no-cache postgresql-libs libssh2 file rsync git jpegoptim vips +RUN apk add --no-cache ffmpeg imagemagick pandoc tectonic oxipng jemalloc # Chequear que la versión de ruby sea la correcta RUN test "2.6.6" = `ruby -e 'puts RUBY_VERSION'` @@ -112,14 +106,11 @@ RUN ln -s data/_public /srv/http/_public # Volver a root para cerrar la compilación USER root - # Sincronizar los assets a un directorio compartido RUN install -m 755 /srv/http/sync_assets.sh /usr/local/bin/sync_assets # Instalar la configuración de monit RUN install -m 640 -o root -g root /srv/http/monit.conf /etc/monit.d/sutty.conf -COPY --from=jemalloc /usr/lib/libjemalloc.so.2 /usr/lib/libjemalloc.so - # Mantener estos directorios! VOLUME "/srv/http/data" diff --git a/Makefile b/Makefile index 78154240..3afc4116 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,23 @@ mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) root_dir := $(patsubst %/,%,$(dir $(mkfile_path))) include $(root_dir)/.env +assets := package.json yarn.lock $(shell find app/assets/ app/javascript/ -type f) + +public/assets-production: $(assets) + rm -rf $@ + RAILS_ENV=production bundle exec rake assets:precompile + mv public/assets $@ + find $@ -type f -name "*.gz" | sed -re "s/\.gz$$//" | xargs -r brotli -k -9 + +public/packs-production: public/packs + rm -rf $@ + mv $< $@ + find $@ -type f | xargs -rI {} sh -c "brotli -k -9 {}; gzip -9 -k {}" + mkdir -p $< + touch $@ + +assets: public/assets-production public/packs-production + serve: bundle exec rails s -b "ssl://0.0.0.0:3000?key=config/sutty.local.key&cert=config/sutty.local.crt" @@ -11,11 +28,11 @@ clean: rm -rf _sites/test-* _deploy/test-* # Generar la imagen Docker -build: - docker build --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/sutty . +build: assets + time docker build --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/sutty . save: - docker save sutty/sutty:latest | gzip | ssh root@sutty.nl docker load + time docker save sutty/sutty:latest | gzip | ssh root@sutty.nl docker load load: ssh root@sutty.nl sh -c "gunzip -c sutty.latest.gz | docker load" @@ -28,7 +45,9 @@ ifeq ($(MAKECMDGOALS),convert-gems) gem_dir := $(shell readlink -f ../gems) gems := $(shell bundle show --paths | xargs -I {} sh -c 'test -f {}/ext/*/extconf.rb && basename {}') gems += $(shell bundle show --paths | xargs -I {} sh -c 'test -f {}/ext/extconf.rb && basename {}') +gems := $(patsubst %-x86_64-linux,%,$(gems)) gems_musl := $(patsubst %,$(gem_dir)/%-x86_64-linux-musl.gem,$(gems)) +gems_gnu := $(patsubst %,$(gem_dir)/%-x86_64-linux.gem,$(gems)) endif $(gem_dir)/%-x86_64-linux-musl.gem: @@ -39,8 +58,22 @@ $(gem_dir)/%-x86_64-linux-musl.gem: -e HTTP_BASIC_PASSWORD=$(HTTP_BASIC_PASSWORD) \ -e GEM=`echo $* | sed -re "s/-[^-]+$$//"` \ -e VERSION=`echo $* | sed -re "s/.*-([^-]+)$$/\1/"` \ + -e JOBS=2 \ + --rm \ sutty/gem-compiler:latest +$(gem_dir)/%-x86_64-linux.gem: + HTTP_BASIC_USER=$(HTTP_BASIC_USER) \ + HTTP_BASIC_PASSWORD=$(HTTP_BASIC_PASSWORD) \ + GEM=`echo $* | sed -re "s/-[^-]+$$//"` \ + VERSION=`echo $* | sed -re "s/.*-([^-]+)$$/\1/"` && \ + cd $(dir $@) && \ + gem fetch --source=https://gems.sutty.nl --platform=ruby \ + --version $${VERSION} $${GEM} && \ + gem compile -V --prune $${GEM}-$${VERSION}.gem && \ + gem inabox -o $@ \ + --host https://$${HTTP_BASIC_USER}:$${HTTP_BASIC_PASSWORD}@gems.sutty.nl + # Compilar todas las gemas binarias y subirlas a gems.sutty.nl para que # al crear el contenedor no tengamos que compilarlas cada vez convert-gems: $(gems_musl)