Skip to content

Commit 91596f9

Browse files
fix: adjust setup to coolify
1 parent aa336a6 commit 91596f9

2 files changed

Lines changed: 85 additions & 134 deletions

File tree

Dockerfile.production

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,86 @@
11
# syntax=docker/dockerfile:1
2-
# ProStaff API - Production Dockerfile
3-
# Multi-stage build for optimized image size
42

5-
# Stage 1: Base
6-
FROM ruby:3.4.5-slim as base
3+
############################
4+
# Base
5+
############################
6+
FROM ruby:3.4.5-slim AS base
77

8-
# Install system dependencies
8+
# Instala dependências essenciais (incluindo curl para healthcheck)
99
RUN apt-get update -qq && \
1010
apt-get install --no-install-recommends -y \
11-
curl \
12-
libpq-dev \
13-
libyaml-dev \
14-
postgresql-client \
15-
tzdata && \
16-
rm -rf /var/lib/apt/lists /var/cache/apt/archives
17-
18-
# Set production environment
11+
curl \
12+
wget \
13+
libpq-dev \
14+
libyaml-dev \
15+
postgresql-client \
16+
tzdata && \
17+
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
18+
1919
ENV RAILS_ENV=production \
2020
BUNDLE_DEPLOYMENT=1 \
2121
BUNDLE_PATH=/usr/local/bundle \
2222
BUNDLE_WITHOUT=development:test
2323

2424
WORKDIR /app
2525

26-
# Stage 2: Build
27-
FROM base as build
26+
############################
27+
# Build Stage
28+
############################
29+
FROM base AS build
2830

29-
# Install build dependencies
3031
RUN apt-get update -qq && \
3132
apt-get install --no-install-recommends -y \
32-
build-essential \
33-
git \
34-
nodejs \
35-
npm && \
33+
build-essential \
34+
git \
35+
nodejs \
36+
npm && \
3637
npm install -g yarn && \
37-
rm -rf /var/lib/apt/lists /var/cache/apt/archives
38+
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
3839

39-
# Copy Gemfile
4040
COPY Gemfile Gemfile.lock ./
4141

42-
# Install gems
4342
RUN bundle install --jobs 4 --retry 3 && \
44-
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
43+
rm -rf /usr/local/bundle/ruby/*/cache && \
44+
rm -rf /usr/local/bundle/ruby/*/bundler/gems/*/.git
4545

46-
# Copy application code
4746
COPY . .
4847

49-
# Precompile bootsnap code for faster boot times
48+
# Precompila bootsnap
5049
RUN bundle exec bootsnap precompile --gemfile app/ lib/
5150

52-
# Stage 3: Production
51+
############################
52+
# Final Stage
53+
############################
5354
FROM base
5455

55-
# Copy built artifacts
56+
# Copia gems e aplicação do estágio de build
5657
COPY --from=build /usr/local/bundle /usr/local/bundle
5758
COPY --from=build /app /app
5859

59-
# Create non-root user
60+
# Cria usuário rails
6061
RUN groupadd --system --gid 1000 rails && \
6162
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
6263
chown -R rails:rails /app /usr/local/bundle
6364

64-
# Create necessary directories
65+
# Cria diretórios necessários
6566
RUN mkdir -p /app/tmp/pids /app/tmp/cache /app/tmp/sockets /app/log && \
6667
chown -R rails:rails /app/tmp /app/log
6768

68-
# Switch to non-root user
6969
USER rails:rails
7070

71-
# Expose port (Railway sets PORT=8080 by default)
72-
EXPOSE 8080
71+
# Porta padrão do Coolify
72+
EXPOSE 3000
7373

74-
# Health check (uses PORT env variable to match runtime configuration)
75-
# Note: Railway has its own health check system, but this is useful for local testing
74+
# Healthcheck para Rails 7+
7675
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
77-
CMD curl -f http://localhost:${PORT:-8080}/up || exit 1
76+
CMD curl -f http://localhost:3000/up || exit 1
7877

79-
# Entry point for database migration
80-
COPY --chown=rails:rails deploy/scripts/docker-entrypoint.sh /usr/local/bin/
78+
# EntryPoint
79+
COPY --chown=rails:rails deploy/scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
8180
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
8281

8382
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
8483

85-
# Start server
84+
# Comando final
8685
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
86+

config/puma.rb

Lines changed: 46 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,83 @@
11
# frozen_string_literal: true
22

3-
# Puma configuration file for ProStaff API
3+
# ================================
4+
# Puma Configuration - ProStaff API
5+
# Optimized for Docker / Coolify
6+
# ================================
47

5-
# Bind to 0.0.0.0 to allow external connections (required for Docker/Railway)
6-
# Note: Use bind instead of port to avoid double-binding issues
8+
# Bind obrigatório para container
79
bind "tcp://0.0.0.0:#{ENV.fetch('PORT', 3000)}"
810

9-
# Specifies the `environment` that Puma will run in.
10-
# If PORT is set (common in production environments), default to production
11-
default_env = ENV['PORT'] ? 'production' : 'development'
12-
environment ENV.fetch('RAILS_ENV', default_env)
11+
# Ambiente
12+
environment ENV.fetch('RAILS_ENV', 'production')
1313

14-
# Specifies the `pidfile` that Puma will use.
14+
# PID (necessário para evitar erro de container restart)
1515
pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
1616

17-
# Specifies the number of `workers` to boot in clustered mode.
18-
# Workers are forked web server processes. If using threads and workers together
19-
# the concurrency of the application would be max `threads` * `workers`.
20-
# Workers do not work on JRuby or Windows (both of which do not support
21-
# processes).
22-
workers ENV.fetch('WEB_CONCURRENCY', 2)
23-
24-
# Use the `preload_app!` method when specifying a `workers` number.
25-
# This directive tells Puma to first boot the application and load code
26-
# before forking the application. This takes advantage of Copy On Write
27-
# process behavior so workers use less memory.
17+
# Threads
18+
max_threads = ENV.fetch('RAILS_MAX_THREADS', 5).to_i
19+
min_threads = ENV.fetch('RAILS_MIN_THREADS', max_threads).to_i
20+
threads min_threads, max_threads
21+
22+
# Workers (IMPORTANTE para container pequeno)
23+
# Se não definir WEB_CONCURRENCY, usa 2
24+
workers ENV.fetch('WEB_CONCURRENCY', 2).to_i
25+
26+
# Preload melhora uso de memória
2827
preload_app!
2928

30-
# Allow puma to be restarted by `rails restart` command.
3129
plugin :tmp_restart
3230

33-
# Specifies the number of `threads` to use per worker.
34-
# This controls how many threads Puma will use to process requests.
35-
# The default is set to 5 threads as a decent default for most Ruby/Rails apps.
36-
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
37-
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
38-
threads min_threads_count, max_threads_count
39-
40-
# === Production Optimizations ===
41-
if %w[production staging].include?(ENV['RAILS_ENV'])
42-
# Increase workers in production
43-
workers ENV.fetch('WEB_CONCURRENCY', 4)
44-
45-
# Bind to socket for better nginx integration (optional)
46-
# bind "unix://#{ENV.fetch('APP_ROOT', Dir.pwd)}/tmp/sockets/puma.sock"
47-
48-
# Logging
49-
stdout_redirect(
50-
ENV.fetch('PUMA_STDOUT_LOG') { "#{Dir.pwd}/log/puma_access.log" },
51-
ENV.fetch('PUMA_STDERR_LOG') { "#{Dir.pwd}/log/puma_error.log" },
52-
true
53-
)
54-
55-
# Worker timeout (seconds)
56-
# Kill workers if they hang for more than this time
57-
worker_timeout ENV.fetch('PUMA_WORKER_TIMEOUT', 60).to_i
31+
# ================================
32+
# Production Settings
33+
# ================================
34+
if ENV['RAILS_ENV'] == 'production'
5835

59-
# Worker boot timeout
36+
# Timeout de worker
37+
worker_timeout ENV.fetch('PUMA_WORKER_TIMEOUT', 60).to_i
6038
worker_boot_timeout ENV.fetch('PUMA_WORKER_BOOT_TIMEOUT', 60).to_i
61-
62-
# Worker shutdown timeout
6339
worker_shutdown_timeout ENV.fetch('PUMA_WORKER_SHUTDOWN_TIMEOUT', 30).to_i
6440

65-
# === Phased Restart (Zero Downtime Deploys) ===
66-
# This allows Puma to restart workers one at a time
67-
# instead of all at once during a restart
68-
# Use: pumactl phased-restart
69-
on_worker_boot do
70-
# Worker specific setup for Rails
71-
# This is needed for preload_app to work with ActiveRecord
72-
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
41+
# Nakayoshi Fork (Puma 7+)
42+
if respond_to?(:nakayoshi_fork) && ENV.fetch('PUMA_NAKAYOSHI_FORK', 'true') == 'true'
43+
nakayoshi_fork
7344
end
7445

46+
# ActiveRecord fix para preload
7547
before_fork do
76-
# Disconnect from database before forking
7748
ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
7849
end
7950

80-
# === Nakayoshi Fork (Memory Optimization) ===
81-
# This reduces memory usage by running GC before forking
82-
# Note: nakayoshi_fork is only available in Puma 7+
83-
if respond_to?(:nakayoshi_fork) && ENV.fetch('PUMA_NAKAYOSHI_FORK', 'true') == 'true'
84-
nakayoshi_fork
51+
on_worker_boot do
52+
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
8553
end
8654

87-
# === Low Level Configuration ===
88-
# Note: Some methods like backlog and tcp_nopush are only available in Puma 7+
89-
# Commenting out for Puma 6 compatibility
90-
91-
# Configure the queue for accepting connections (Puma 7+ only)
92-
# backlog ENV.fetch('PUMA_BACKLOG', 1024).to_i if respond_to?(:backlog)
93-
94-
# Set the TCP_CORK and TCP_NODELAY options (Puma 7+ only)
95-
# tcp_nopush true if respond_to?(:tcp_nopush) && ENV.fetch('PUMA_TCP_NOPUSH', 'true') == 'true'
96-
97-
# === Monitoring ===
98-
# Activate control/status app
99-
# Allows you to query Puma for stats and control it
100-
# Access via: pumactl stats -C unix://#{Dir.pwd}/tmp/sockets/pumactl.sock
101-
activate_control_app "unix://#{Dir.pwd}/tmp/sockets/pumactl.sock", { no_token: true }
55+
# Removido activate_control_app
10256
end
10357

104-
# === Development Optimizations ===
58+
# ================================
59+
# Development
60+
# ================================
10561
if ENV['RAILS_ENV'] == 'development'
106-
# Use fewer workers in development
10762
workers 0
108-
109-
# Verbose logging in development
11063
debug true if ENV.fetch('PUMA_DEBUG', 'false') == 'true'
11164
end
11265

113-
# === Callbacks ===
66+
# ================================
67+
# Logs (container-friendly)
68+
# ================================
69+
# Melhor prática para Docker:
70+
# logar no STDOUT ao invés de arquivos
71+
stdout_redirect nil, nil, true
72+
73+
# ================================
74+
# Boot logs
75+
# ================================
11476
on_booted do
115-
puts "🚀 Puma booted (PID: #{Process.pid})"
77+
puts " Puma booted (PID: #{Process.pid})"
11678
puts " Environment: #{ENV['RAILS_ENV']}"
11779
puts " Workers: #{ENV.fetch('WEB_CONCURRENCY', 2)}"
118-
puts " Threads: #{min_threads_count}-#{max_threads_count}"
80+
puts " Threads: #{min_threads}-#{max_threads}"
11981
puts " Port: #{ENV.fetch('PORT', 3000)}"
12082
end
12183

122-
on_worker_boot do |worker_index|
123-
puts "👷 Worker #{worker_index} booted (PID: #{Process.pid})"
124-
end
125-
126-
on_worker_shutdown do |worker_index|
127-
puts "👷 Worker #{worker_index} shutting down (PID: #{Process.pid})"
128-
end
129-
130-
# === Health Check Endpoint ===
131-
# This is automatically handled by Rails /up endpoint
132-
# No additional configuration needed here

0 commit comments

Comments
 (0)