diff --git a/Dockerfile b/Dockerfile index af24c81..2728ae4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,13 +13,24 @@ ENV RAILS_ENV="production" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" +# Install packages needed for SSL and build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y \ + openssl build-essential git libvips pkg-config \ + curl libsqlite3-0 libvips && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives -# Throw-away build stage to reduce size of final image -FROM base as build +# Generate self-signed SSL certificates in /app/ssl directory +RUN mkdir -p /rails/app/ssl && \ + openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \ + -keyout /rails/app/ssl/server.key -out /rails/app/ssl/server.crt \ + -subj "/C=US/ST=State/L=City/O=Organization/OU=Unit/CN=localhost" -# Install packages needed to build gems -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git libvips pkg-config +# Copy application code +COPY . . + +# Throw-away build stage to reduce size of final image, though still chunky, need to refine it further later +FROM base as build # Install application gems COPY Gemfile Gemfile.lock ./ @@ -41,14 +52,8 @@ RUN chmod +x bin/* && \ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile - # Final stage for app image -FROM base - -# Install packages needed for deployment -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \ - rm -rf /var/lib/apt/lists /var/cache/apt/archives +FROM base as final # Copy built artifacts: gems, application COPY --from=build /usr/local/bundle /usr/local/bundle @@ -56,12 +61,18 @@ COPY --from=build /rails /rails # Run and own only the runtime files as a non-root user for security RUN useradd rails --create-home --shell /bin/bash && \ - chown -R rails:rails db log storage tmp -USER rails:rails + chown -R rails:rails /rails/db /rails/log /rails/storage /rails/tmp + +# Configure Rails to use SSL from /rails/app/ssl directory +COPY --from=build /rails/app/ssl /rails/app/ssl + +# Change permissions for SSL files +RUN chmod 600 /rails/app/ssl/server.key /rails/app/ssl/server.crt -# Entrypoint prepares the database. -ENTRYPOINT ["/rails/bin/docker-entrypoint"] +# Entrypoint prepares the database and generates secret key base. +COPY --from=build /rails/bin/docker-entrypoint /rails/bin/docker-entrypoint +RUN chmod +x /rails/bin/docker-entrypoint # Start the server by default, this can be overwritten at runtime -EXPOSE 3000 +EXPOSE 3000 3001 CMD ["./bin/rails", "server"] diff --git a/config/environments/production.rb b/config/environments/production.rb index c2c1571..a218c0c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -49,7 +49,7 @@ # config.assume_ssl = true # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true + config.force_ssl = false # Log to STDOUT by default config.logger = ActiveSupport::Logger.new(STDOUT) diff --git a/config/puma.rb b/config/puma.rb index afa809b..0a7b227 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -22,6 +22,17 @@ # terminating a worker in development environments. worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" +# Use SSL in production +if ENV["RAILS_ENV"] == "production" + ssl_bind '0.0.0.0', '3001', { + key: "/rails/app/ssl/server.key", + cert: "/rails/app/ssl/server.crt", + verify_mode: "none" # Use 'peer' if you have a CA-signed certificate + } +else + bind 'tcp://0.0.0.0:3000' +end + # Specifies the `port` that Puma will listen on to receive requests; default is 3000. port ENV.fetch("PORT") { 3000 }