Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Don't include any of these files in the Dockerfile build context.
# This will improve build performance and reduce the final image size.
# See: https://docs.docker.com/engine/reference/builder/#dockerignore-file
.git/
.github/
.dockerignore
Expand All @@ -9,5 +8,12 @@
.rubocop.yml
CHANGELOG.md
docker-compose.yml
log/
node_modules/
log/*
tmp/*
!log/.keep
!tmp/.keep
storage/*
public/assets
public/packs
test/
38 changes: 29 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The image to build from.
FROM ruby:3.2.1
FROM ruby:3.2.1-slim

# Properties/labels for the image.
LABEL maintainer="Notebook.ai Contributors"
Expand All @@ -12,14 +12,24 @@ ENV RAILS_ENV=${RAILS_ENV}
RUN groupadd --system --gid 1000 notebookai && \
useradd --system --home-dir /home/notebookai --gid notebookai --uid 1000 --shell /bin/bash notebookai

# Install system dependencies
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \
apt-get update -qq && \
apt-get install -y build-essential libpq-dev nodejs imagemagick libmagickwand-dev curl && \
# Install system dependencies (including curl which is needed for Node download, and git for Bundler)
RUN apt-get update -qq && \
apt-get install -y build-essential libpq-dev imagemagick libmagickwand-dev curl git libjemalloc2 && \
rm --recursive --force /var/lib/apt/lists/*

# Install yarn via npm (avoids the deprecated apt-key approach)
RUN npm install -g yarn
# Install Node.js 16.x explicitly and support both ARM and x64 architectures
RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" && \
case "${dpkgArch##*-}" in \
amd64) ARCH='x64';; \
arm64) ARCH='arm64';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
curl -fsSLO "https://nodejs.org/dist/v16.20.2/node-v16.20.2-linux-$ARCH.tar.gz" && \
tar -xzf "node-v16.20.2-linux-$ARCH.tar.gz" -C /usr/local --strip-components=1 && \
rm "node-v16.20.2-linux-$ARCH.tar.gz"

# Install yarn via npm (matches local tools specification)
RUN npm install -g yarn@1.22.22

# Set the notebookai user's home directory as the working directory.
WORKDIR /home/notebookai
Expand All @@ -37,11 +47,21 @@ COPY . .
# Adjust permissions on all copied files to match the system user
RUN chown -R notebookai:notebookai /home/notebookai

# Drop down to the unprivileged user before running Rake, so any files it generates (like logs) are owned correctly
USER notebookai

# Precompile assets during docker build to prevent OOM memory spikes at runtime
# We strictly limit Node.js memory to 1GB to prevent Railway's Builder container from OOMing
RUN NODE_OPTIONS="--max_old_space_size=1024" SECRET_KEY_BASE=dummy bundle exec rake assets:precompile

# This image should expose port 3000.
EXPOSE 3000/tcp

# Run unprivileged
USER notebookai
# Enable jemalloc to drastically reduce memory fragmentation and usage
ENV LD_PRELOAD="libjemalloc.so.2"

# Configure the main process to run when running the image
ENTRYPOINT ["./docker-entrypoint.sh"]

# Start the server using Puma!
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb", "-e", "development", "-b", "tcp://0.0.0.0:3000"]
7 changes: 6 additions & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Allow PR environments on Railway (auto-deployed dynamic domains)
config.hosts << /.*\.up\.railway\.app/
config.hosts << ENV["RAILWAY_PUBLIC_DOMAIN"] if ENV["RAILWAY_PUBLIC_DOMAIN"].present?

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = true
# We set this to false to save hundreds of megabytes of memory on boot.
config.eager_load = false

# Show full error reports.
config.consider_all_requests_local = true
Expand Down
4 changes: 4 additions & 0 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Allow PR environments on Railway (auto-deployed dynamic domains)
config.hosts << /.*\.up\.railway\.app/
config.hosts << ENV["RAILWAY_PUBLIC_DOMAIN"] if ENV["RAILWAY_PUBLIC_DOMAIN"].present?

# Code is not reloaded between requests.
config.cache_classes = true

Expand Down
3 changes: 2 additions & 1 deletion config/puma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# In development, default to 0 workers (single mode) to save memory and allow for easier debugging.
workers ENV.fetch("WEB_CONCURRENCY") { ENV.fetch("RAILS_ENV", "development") == "development" ? 0 : 2 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ services:
build: .
ports:
- "3000:3000/tcp"
command: sh -c "rake db:migrate && rm -f tmp/pids/server.pid && exec rails server -b 0.0.0.0"
command: sh -c "rake db:migrate && exec rails server -b 0.0.0.0"
volumes:
- "./:/home/notebookai"
12 changes: 12 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /home/notebookai/tmp/pids/server.pid

# Ensure the database is prepared (migrated & seeded) before starting the server
bundle exec rails db:prepare
bundle exec rails db:seed

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Loading