Unify Dockerfile

This commit is contained in:
Eugene Burmakin 2025-11-07 12:38:44 +01:00
parent d40514c5f8
commit 6a42a170e7
4 changed files with 304 additions and 43 deletions

View file

@ -96,7 +96,7 @@ jobs:
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
file: ./docker/Dockerfile.dev file: ./docker/Dockerfile
push: true push: true
tags: ${{ steps.docker_meta.outputs.tags }} tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}

140
docker/.env.example Normal file
View file

@ -0,0 +1,140 @@
# Dawarich Docker Compose Configuration
# Copy this file to .env and customize for your environment
# =============================================================================
# ENVIRONMENT CONFIGURATION
# =============================================================================
# Rails environment: development, staging, or production
RAILS_ENV=development
# =============================================================================
# DATABASE CONFIGURATION
# =============================================================================
# PostgreSQL credentials
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
# Database name - will default to dawarich_${RAILS_ENV}
# For development: dawarich_development
# For staging: dawarich_staging
# For production: dawarich_production
POSTGRES_DB=dawarich_development
# Database connection settings (used by Rails app)
DATABASE_HOST=dawarich_db
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=password
DATABASE_NAME=dawarich_development
# =============================================================================
# REDIS CONFIGURATION
# =============================================================================
# Redis connection URL
REDIS_URL=redis://dawarich_redis:6379
# =============================================================================
# APPLICATION SETTINGS
# =============================================================================
# Port to expose the application on
DAWARICH_APP_PORT=3000
# Application hosts (comma-separated)
# Development: localhost
# Production: your-domain.com,www.your-domain.com
APPLICATION_HOSTS=localhost,::1,127.0.0.1
# Application protocol (http or https)
APPLICATION_PROTOCOL=http
# Time zone
TIME_ZONE=Europe/London
# Minimum minutes spent in city for statistics
MIN_MINUTES_SPENT_IN_CITY=60
# Self-hosted flag (true for docker deployments)
SELF_HOSTED=true
# Store geodata (reverse geocoding results)
STORE_GEODATA=true
# =============================================================================
# SECURITY
# =============================================================================
# Secret key base for production/staging
# Generate with: openssl rand -hex 64
# Leave empty for development (will auto-generate)
SECRET_KEY_BASE=
# =============================================================================
# BACKGROUND JOBS
# =============================================================================
# Sidekiq concurrency (number of threads)
BACKGROUND_PROCESSING_CONCURRENCY=10
# =============================================================================
# MONITORING & LOGGING
# =============================================================================
# Prometheus exporter settings
PROMETHEUS_EXPORTER_ENABLED=false
PROMETHEUS_EXPORTER_HOST=0.0.0.0
PROMETHEUS_EXPORTER_PORT=9394
PROMETHEUS_EXPORTER_HOST_SIDEKIQ=dawarich_app
# Uncomment to expose Prometheus port
# PROMETHEUS_PORT=9394
# Rails logging
RAILS_LOG_TO_STDOUT=true
# Docker logging settings
LOG_MAX_SIZE=100m
LOG_MAX_FILE=5
# =============================================================================
# RESOURCE LIMITS
# =============================================================================
# CPU and memory limits for the app container
APP_CPU_LIMIT=0.50
APP_MEMORY_LIMIT=4G
# =============================================================================
# EXAMPLE CONFIGURATIONS BY ENVIRONMENT
# =============================================================================
# --- DEVELOPMENT ---
# RAILS_ENV=development
# POSTGRES_DB=dawarich_development
# DATABASE_NAME=dawarich_development
# APPLICATION_HOSTS=localhost,::1,127.0.0.1
# APPLICATION_PROTOCOL=http
# SECRET_KEY_BASE=
# SELF_HOSTED=true
# --- STAGING ---
# RAILS_ENV=staging
# POSTGRES_DB=dawarich_staging
# DATABASE_NAME=dawarich_staging
# APPLICATION_HOSTS=staging.example.com
# APPLICATION_PROTOCOL=https
# SECRET_KEY_BASE=your-generated-secret-key
# SELF_HOSTED=true
# --- PRODUCTION ---
# RAILS_ENV=production
# POSTGRES_DB=dawarich_production
# DATABASE_NAME=dawarich_production
# APPLICATION_HOSTS=dawarich.example.com,www.dawarich.example.com
# APPLICATION_PROTOCOL=https
# SECRET_KEY_BASE=your-generated-secret-key
# SELF_HOSTED=true
# PROMETHEUS_EXPORTER_ENABLED=true

110
docker/Dockerfile Normal file
View file

@ -0,0 +1,110 @@
FROM ruby:3.4.6-slim
ARG RAILS_ENV=production
ENV APP_PATH=/var/app
ENV BUNDLE_VERSION=2.5.21
ENV BUNDLE_PATH=/usr/local/bundle/gems
ENV RAILS_LOG_TO_STDOUT=true
ENV RAILS_PORT=3000
ENV RAILS_ENV=${RAILS_ENV}
# Development-specific environment variables
RUN if [ "$RAILS_ENV" = "development" ]; then \
echo "export SELF_HOSTED=true" >> /etc/profile.d/rails.sh && \
echo "export SIDEKIQ_USERNAME=sidekiq" >> /etc/profile.d/rails.sh && \
echo "export SIDEKIQ_PASSWORD=password" >> /etc/profile.d/rails.sh && \
echo "export PGSSENCMODE=disable" >> /etc/profile.d/rails.sh; \
fi
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
wget \
build-essential \
git \
postgresql-client \
libpq-dev \
libxml2-dev \
libxslt-dev \
libyaml-dev \
libgeos-dev libgeos++-dev \
imagemagick \
tzdata \
less \
libjemalloc2 libjemalloc-dev \
cmake \
ca-certificates \
&& mkdir -p $APP_PATH \
&& rm -rf /var/lib/apt/lists/*
# Install Node.js with architecture-specific logic for development
# For production/staging, use LTS version
RUN if [ "$RAILS_ENV" = "development" ]; then \
ARCH=$(dpkg --print-architecture) && \
if [ "$ARCH" = "amd64" ] || [ "$ARCH" = "arm64" ] || [ "$ARCH" = "armhf" ]; then \
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
apt-get install -y nodejs; \
else \
apt-get update && \
apt-get install -y nodejs npm; \
fi; \
else \
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
apt-get install -y nodejs; \
fi && \
npm install -g yarn && \
rm -rf /var/lib/apt/lists/*
# Use jemalloc with check for architecture
RUN if [ "$(uname -m)" = "x86_64" ]; then \
echo "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2" > /etc/ld.so.preload; \
else \
echo "/usr/lib/aarch64-linux-gnu/libjemalloc.so.2" > /etc/ld.so.preload; \
fi
# Enable YJIT
ENV RUBY_YJIT_ENABLE=1
# Update RubyGems and install Bundler
RUN gem update --system 3.6.9 \
&& gem install bundler --version "$BUNDLE_VERSION" \
&& rm -rf $GEM_HOME/cache/*
WORKDIR $APP_PATH
COPY ../Gemfile ../Gemfile.lock ../.ruby-version ../vendor ./
# Install gems based on environment
RUN bundle config set --local path 'vendor/bundle' \
&& if [ "$RAILS_ENV" = "production" ] || [ "$RAILS_ENV" = "staging" ]; then \
bundle config set --local without 'development test' && \
bundle install --jobs 4 --retry 3; \
else \
bundle install --jobs 4 --retry 3; \
fi \
&& rm -rf vendor/bundle/ruby/3.4.0/cache/*.gem
COPY ../. ./
# Precompile assets for production/staging
RUN if [ "$RAILS_ENV" = "production" ] || [ "$RAILS_ENV" = "staging" ]; then \
SECRET_KEY_BASE_DUMMY=1 bundle exec rake assets:precompile && \
rm -rf node_modules tmp/cache; \
fi
# Create caching-dev.txt file for development
RUN if [ "$RAILS_ENV" = "development" ]; then \
mkdir -p $APP_PATH/tmp && touch $APP_PATH/tmp/caching-dev.txt; \
fi
COPY ./docker/web-entrypoint.sh /usr/local/bin/web-entrypoint.sh
RUN chmod +x /usr/local/bin/web-entrypoint.sh
COPY ./docker/sidekiq-entrypoint.sh /usr/local/bin/sidekiq-entrypoint.sh
RUN chmod +x /usr/local/bin/sidekiq-entrypoint.sh
EXPOSE $RAILS_PORT
ENTRYPOINT ["bundle", "exec"]

View file

@ -1,5 +1,6 @@
networks: networks:
dawarich: dawarich:
services: services:
dawarich_redis: dawarich_redis:
image: redis:7.4-alpine image: redis:7.4-alpine
@ -8,7 +9,7 @@ services:
networks: networks:
- dawarich - dawarich
volumes: volumes:
- dawarich_shared:/data - dawarich_redis_data:/data
restart: always restart: always
healthcheck: healthcheck:
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ] test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
@ -16,6 +17,7 @@ services:
retries: 5 retries: 5
start_period: 30s start_period: 30s
timeout: 10s timeout: 10s
dawarich_db: dawarich_db:
image: postgis/postgis:17-3.5-alpine image: postgis/postgis:17-3.5-alpine
shm_size: 1G shm_size: 1G
@ -27,17 +29,18 @@ services:
networks: networks:
- dawarich - dawarich
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: password POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_DB: dawarich_development POSTGRES_DB: ${POSTGRES_DB:-dawarich_development}
restart: always restart: always
healthcheck: healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres -d dawarich_development" ] test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-dawarich_development}" ]
interval: 10s interval: 10s
retries: 5 retries: 5
start_period: 30s start_period: 30s
timeout: 10s timeout: 10s
# command: postgres -c config_file=/etc/postgresql/postgresql.conf # Use custom config, uncomment if you want to use a custom config # command: postgres -c config_file=/etc/postgresql/postgresql.conf # Use custom config, uncomment if you want to use a custom config
dawarich_app: dawarich_app:
image: freikin/dawarich:latest image: freikin/dawarich:latest
container_name: dawarich_app container_name: dawarich_app
@ -49,34 +52,37 @@ services:
networks: networks:
- dawarich - dawarich
ports: ports:
- 3000:3000 - "${DAWARICH_APP_PORT:-3000}:3000"
# - 9394:9394 # Prometheus exporter, uncomment if needed # - "${PROMETHEUS_PORT:-9394}:9394" # Prometheus exporter, uncomment if needed
stdin_open: true stdin_open: true
tty: true tty: true
entrypoint: web-entrypoint.sh entrypoint: web-entrypoint.sh
command: ['bin/rails', 'server', '-p', '3000', '-b', '::'] command: ['bin/rails', 'server', '-p', '3000', '-b', '::']
restart: on-failure restart: on-failure
environment: environment:
RAILS_ENV: development RAILS_ENV: ${RAILS_ENV:-development}
REDIS_URL: redis://dawarich_redis:6379 REDIS_URL: ${REDIS_URL:-redis://dawarich_redis:6379}
DATABASE_HOST: dawarich_db DATABASE_HOST: ${DATABASE_HOST:-dawarich_db}
DATABASE_USERNAME: postgres DATABASE_PORT: ${DATABASE_PORT:-5432}
DATABASE_PASSWORD: password DATABASE_USERNAME: ${DATABASE_USERNAME:-postgres}
DATABASE_NAME: dawarich_development DATABASE_PASSWORD: ${DATABASE_PASSWORD:-password}
MIN_MINUTES_SPENT_IN_CITY: 60 DATABASE_NAME: ${DATABASE_NAME:-dawarich_development}
APPLICATION_HOSTS: localhost MIN_MINUTES_SPENT_IN_CITY: ${MIN_MINUTES_SPENT_IN_CITY:-60}
TIME_ZONE: Europe/London APPLICATION_HOSTS: ${APPLICATION_HOSTS:-localhost,::1,127.0.0.1}
APPLICATION_PROTOCOL: http TIME_ZONE: ${TIME_ZONE:-Europe/London}
PROMETHEUS_EXPORTER_ENABLED: "false" APPLICATION_PROTOCOL: ${APPLICATION_PROTOCOL:-http}
PROMETHEUS_EXPORTER_HOST: 0.0.0.0 PROMETHEUS_EXPORTER_ENABLED: ${PROMETHEUS_EXPORTER_ENABLED:-false}
PROMETHEUS_EXPORTER_PORT: 9394 PROMETHEUS_EXPORTER_HOST: ${PROMETHEUS_EXPORTER_HOST:-0.0.0.0}
SELF_HOSTED: "true" PROMETHEUS_EXPORTER_PORT: ${PROMETHEUS_EXPORTER_PORT:-9394}
STORE_GEODATA: "true" SECRET_KEY_BASE: ${SECRET_KEY_BASE:-}
RAILS_LOG_TO_STDOUT: ${RAILS_LOG_TO_STDOUT:-true}
SELF_HOSTED: ${SELF_HOSTED:-true}
STORE_GEODATA: ${STORE_GEODATA:-true}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:
max-size: "100m" max-size: ${LOG_MAX_SIZE:-100m}
max-file: "5" max-file: ${LOG_MAX_FILE:-5}
healthcheck: healthcheck:
test: [ "CMD-SHELL", "wget -qO - http://127.0.0.1:3000/api/v1/health | grep -q '\"status\"\\s*:\\s*\"ok\"'" ] test: [ "CMD-SHELL", "wget -qO - http://127.0.0.1:3000/api/v1/health | grep -q '\"status\"\\s*:\\s*\"ok\"'" ]
interval: 10s interval: 10s
@ -93,8 +99,9 @@ services:
deploy: deploy:
resources: resources:
limits: limits:
cpus: '0.50' # Limit CPU usage to 50% of one core cpus: ${APP_CPU_LIMIT:-0.50}
memory: '4G' # Limit memory usage to 4GB memory: ${APP_MEMORY_LIMIT:-4G}
dawarich_sidekiq: dawarich_sidekiq:
image: freikin/dawarich:latest image: freikin/dawarich:latest
container_name: dawarich_sidekiq container_name: dawarich_sidekiq
@ -110,25 +117,28 @@ services:
command: ['sidekiq'] command: ['sidekiq']
restart: on-failure restart: on-failure
environment: environment:
RAILS_ENV: development RAILS_ENV: ${RAILS_ENV:-development}
REDIS_URL: redis://dawarich_redis:6379 REDIS_URL: ${REDIS_URL:-redis://dawarich_redis:6379}
DATABASE_HOST: dawarich_db DATABASE_HOST: ${DATABASE_HOST:-dawarich_db}
DATABASE_USERNAME: postgres DATABASE_PORT: ${DATABASE_PORT:-5432}
DATABASE_PASSWORD: password DATABASE_USERNAME: ${DATABASE_USERNAME:-postgres}
DATABASE_NAME: dawarich_development DATABASE_PASSWORD: ${DATABASE_PASSWORD:-password}
APPLICATION_HOSTS: localhost DATABASE_NAME: ${DATABASE_NAME:-dawarich_development}
BACKGROUND_PROCESSING_CONCURRENCY: 10 APPLICATION_HOSTS: ${APPLICATION_HOSTS:-localhost,::1,127.0.0.1}
APPLICATION_PROTOCOL: http BACKGROUND_PROCESSING_CONCURRENCY: ${BACKGROUND_PROCESSING_CONCURRENCY:-10}
PROMETHEUS_EXPORTER_ENABLED: "false" APPLICATION_PROTOCOL: ${APPLICATION_PROTOCOL:-http}
PROMETHEUS_EXPORTER_HOST: dawarich_app PROMETHEUS_EXPORTER_ENABLED: ${PROMETHEUS_EXPORTER_ENABLED:-false}
PROMETHEUS_EXPORTER_PORT: 9394 PROMETHEUS_EXPORTER_HOST: ${PROMETHEUS_EXPORTER_HOST_SIDEKIQ:-dawarich_app}
SELF_HOSTED: "true" PROMETHEUS_EXPORTER_PORT: ${PROMETHEUS_EXPORTER_PORT:-9394}
STORE_GEODATA: "true" SECRET_KEY_BASE: ${SECRET_KEY_BASE:-}
RAILS_LOG_TO_STDOUT: ${RAILS_LOG_TO_STDOUT:-true}
SELF_HOSTED: ${SELF_HOSTED:-true}
STORE_GEODATA: ${STORE_GEODATA:-true}
logging: logging:
driver: "json-file" driver: "json-file"
options: options:
max-size: "100m" max-size: ${LOG_MAX_SIZE:-100m}
max-file: "5" max-file: ${LOG_MAX_FILE:-5}
healthcheck: healthcheck:
test: [ "CMD-SHELL", "pgrep -f sidekiq" ] test: [ "CMD-SHELL", "pgrep -f sidekiq" ]
interval: 10s interval: 10s
@ -148,6 +158,7 @@ services:
volumes: volumes:
dawarich_db_data: dawarich_db_data:
dawarich_redis_data:
dawarich_shared: dawarich_shared:
dawarich_public: dawarich_public:
dawarich_watched: dawarich_watched: