diff --git a/.github/workflows/build_and_push.yml b/.github/workflows/build_and_push.yml index 2c1ebe4c..05173d53 100644 --- a/.github/workflows/build_and_push.yml +++ b/.github/workflows/build_and_push.yml @@ -40,7 +40,7 @@ jobs: uses: docker/build-push-action@v2 with: context: . - file: ./Dockerfile + file: ./docker/Dockerfile push: true tags: freikin/dawarich:latest,freikin/dawarich:${{ github.event.inputs.branch || github.ref_name }} platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 diff --git a/dev-docker-sidekiq-entrypoint.sh b/dev-docker-sidekiq-entrypoint.sh deleted file mode 100644 index db7c87e9..00000000 --- a/dev-docker-sidekiq-entrypoint.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -set -e - -echo "Environment: $RAILS_ENV" - -# set env var defaults -DATABASE_HOST=${DATABASE_HOST:-"dawarich_db"} -DATABASE_PORT=${DATABASE_PORT:-5432} -DATABASE_USER=${DATABASE_USER:-"postgres"} -DATABASE_PASSWORD=${DATABASE_PASSWORD:-"password"} -DATABASE_NAME=${DATABASE_NAME:-"dawarich_development"} - -# Wait for the database to be ready -until nc -zv $DATABASE_HOST ${DATABASE_PORT:-5432}; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 -done - -# run passed commands -bundle exec ${@} diff --git a/.dockerignore b/docker/.dockerignore similarity index 100% rename from .dockerignore rename to docker/.dockerignore diff --git a/Dockerfile b/docker/Dockerfile similarity index 83% rename from Dockerfile rename to docker/Dockerfile index ef2b74c5..07334a1f 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -32,17 +32,17 @@ RUN gem install bundler --version "$BUNDLE_VERSION" \ # Navigate to app directory WORKDIR $APP_PATH -COPY Gemfile Gemfile.lock vendor .ruby-version ./ +COPY ../Gemfile ../Gemfile.lock ../vendor ../.ruby-version ./ # Install missing gems RUN bundle config set --local path 'vendor/bundle' \ && bundle install --jobs 20 --retry 5 -COPY . ./ +COPY ../. ./ # Copy entrypoint scripts and grant execution permissions -COPY ./dev-docker-entrypoint.sh /usr/local/bin/dev-entrypoint.sh -RUN chmod +x /usr/local/bin/dev-entrypoint.sh +COPY ./docker/prod-docker-entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh EXPOSE $RAILS_PORT diff --git a/Dockerfile.dev b/docker/Dockerfile.dev similarity index 100% rename from Dockerfile.dev rename to docker/Dockerfile.dev diff --git a/dev-docker-entrypoint.sh b/docker/dev-docker-entrypoint.sh similarity index 92% rename from dev-docker-entrypoint.sh rename to docker/dev-docker-entrypoint.sh index 385b50da..90a8ddfd 100644 --- a/dev-docker-entrypoint.sh +++ b/docker/dev-docker-entrypoint.sh @@ -24,8 +24,8 @@ until nc -zv $DATABASE_HOST ${DATABASE_PORT:-5432}; do done # Install gems -gem update --system 3.5.7 -gem install bundler --version '2.5.9' +gem update --system 3.6.2 +gem install bundler --version '2.5.21' # Create the database if [ "$(psql "postgres://$DATABASE_USERNAME:$DATABASE_PASSWORD@$DATABASE_HOST:$DATABASE_PORT" -XtAc "SELECT 1 FROM pg_database WHERE datname='$DATABASE_NAME'")" = '1' ]; then @@ -37,7 +37,7 @@ fi # Run database migrations echo "PostgreSQL is ready. Running database migrations..." -bundle exec rails db:prepare +bundle exec rails db:migrate # Run data migrations echo "Running DATA migrations..." diff --git a/docker-compose.production.yml b/docker/docker-compose.production.yml similarity index 89% rename from docker-compose.production.yml rename to docker/docker-compose.production.yml index e6a39b90..2399e731 100644 --- a/docker-compose.production.yml +++ b/docker/docker-compose.production.yml @@ -2,7 +2,7 @@ networks: dawarich: services: dawarich_redis: - image: redis:7.0-alpine + image: redis:7.4-alpine container_name: dawarich_redis command: redis-server networks: @@ -17,7 +17,7 @@ services: start_period: 30s timeout: 10s dawarich_db: - image: postgres:14.2-alpine + image: postgres:17-alpine container_name: dawarich_db volumes: - db_data:/var/lib/postgresql/data @@ -27,15 +27,16 @@ services: environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password + POSTGRES_DB: dawarich_production restart: always healthcheck: - test: [ "CMD-SHELL", "pg_isready -U postgres -d dawarich_development" ] + test: [ "CMD", "pg_isready", "-U", "postgres" ] interval: 10s retries: 5 start_period: 30s timeout: 10s dawarich_app: - image: freikin/dawarich:latest + image: dawarich:prod container_name: dawarich_app volumes: - gem_cache:/usr/local/bundle/gems_app @@ -48,16 +49,17 @@ services: # - 9394:9394 # Prometheus exporter, uncomment if needed stdin_open: true tty: true - entrypoint: dev-entrypoint.sh + entrypoint: entrypoint.sh command: ['bin/dev'] restart: on-failure environment: RAILS_ENV: production REDIS_URL: redis://dawarich_redis:6379/0 DATABASE_HOST: dawarich_db + DATABASE_PORT: 5432 DATABASE_USERNAME: postgres DATABASE_PASSWORD: password - DATABASE_NAME: dawarich_development + DATABASE_NAME: dawarich_production MIN_MINUTES_SPENT_IN_CITY: 60 APPLICATION_HOST: localhost APPLICATION_HOSTS: localhost @@ -69,6 +71,8 @@ services: PROMETHEUS_EXPORTER_ENABLED: false PROMETHEUS_EXPORTER_HOST: 0.0.0.0 PROMETHEUS_EXPORTER_PORT: 9394 + SECRET_KEY_BASE: 1234567890 + RAILS_LOG_TO_STDOUT: "true" logging: driver: "json-file" options: @@ -93,7 +97,7 @@ services: cpus: '0.50' # Limit CPU usage to 50% of one core memory: '2G' # Limit memory usage to 2GB dawarich_sidekiq: - image: freikin/dawarich:latest + image: dawarich:prod container_name: dawarich_sidekiq volumes: - gem_cache:/usr/local/bundle/gems_sidekiq @@ -103,16 +107,17 @@ services: - dawarich stdin_open: true tty: true - entrypoint: dev-entrypoint.sh + entrypoint: entrypoint.sh command: ['sidekiq'] restart: on-failure environment: RAILS_ENV: production REDIS_URL: redis://dawarich_redis:6379/0 DATABASE_HOST: dawarich_db + DATABASE_PORT: 5432 DATABASE_USERNAME: postgres DATABASE_PASSWORD: password - DATABASE_NAME: dawarich_development + DATABASE_NAME: dawarich_production APPLICATION_HOST: localhost APPLICATION_HOSTS: localhost BACKGROUND_PROCESSING_CONCURRENCY: 10 diff --git a/docker-compose.yml b/docker/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to docker/docker-compose.yml diff --git a/docker-compose_mounted_volumes.yml b/docker/docker-compose_mounted_volumes.yml similarity index 100% rename from docker-compose_mounted_volumes.yml rename to docker/docker-compose_mounted_volumes.yml diff --git a/docker/prod-docker-entrypoint.sh b/docker/prod-docker-entrypoint.sh new file mode 100644 index 00000000..683ae2f0 --- /dev/null +++ b/docker/prod-docker-entrypoint.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +unset BUNDLE_PATH +unset BUNDLE_BIN + +set -e + +echo "Environment: $RAILS_ENV" + +# Parse DATABASE_URL if present, otherwise use individual variables +if [ -n "$DATABASE_URL" ]; then + # Extract components from DATABASE_URL + DATABASE_HOST=$(echo $DATABASE_URL | awk -F[@/] '{print $4}') + DATABASE_PORT=$(echo $DATABASE_URL | awk -F[@/:] '{print $5}') + DATABASE_USERNAME=$(echo $DATABASE_URL | awk -F[:/@] '{print $4}') + DATABASE_PASSWORD=$(echo $DATABASE_URL | awk -F[:/@] '{print $5}') + DATABASE_NAME=$(echo $DATABASE_URL | awk -F[@/] '{print $5}') +else + # Use existing environment variables + DATABASE_HOST=${DATABASE_HOST:-dawarich_db} + DATABASE_PORT=${DATABASE_PORT:-5432} + DATABASE_USERNAME=${DATABASE_USERNAME:-postgres} + DATABASE_PASSWORD=${DATABASE_PASSWORD:-password} + DATABASE_NAME=${DATABASE_NAME:-dawarich_production} +fi + +# Function to test database connection +test_db_connection() { + echo "Testing connection to PostgreSQL..." + echo "Host: $DATABASE_HOST" + echo "Port: $DATABASE_PORT" + echo "Username: $DATABASE_USERNAME" + echo "Database: postgres (default database)" + + if PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USERNAME" -d postgres -c "SELECT 1" > /dev/null 2>&1; then + echo "✅ Successfully connected to PostgreSQL!" + return 0 + else + echo "❌ Failed to connect to PostgreSQL" + return 1 + fi +} + +# Try to connect to PostgreSQL, with a timeout +max_attempts=30 +attempt=1 + +while ! test_db_connection; do + if [ $attempt -ge $max_attempts ]; then + echo "Failed to connect to PostgreSQL after $max_attempts attempts. Exiting." + exit 1 + fi + + echo "Attempt $attempt of $max_attempts. Waiting 2 seconds before retry..." + attempt=$((attempt + 1)) + sleep 2 +done + +# Remove pre-existing puma/passenger server.pid +rm -f $APP_PATH/tmp/pids/server.pid + +# Install gems +gem update --system 3.6.2 +gem install bundler --version '2.5.21' + +# Create the database if it doesn't exist +if PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USERNAME" -c "SELECT 1 FROM pg_database WHERE datname='$DATABASE_NAME'" | grep -q 1; then + echo "Database $DATABASE_NAME already exists, skipping creation..." +else + echo "Creating database $DATABASE_NAME..." + bundle exec rails db:create +fi + +# Run database migrations +echo "PostgreSQL is ready. Running database migrations..." +bundle exec rails db:migrate + +# Run data migrations +echo "Running DATA migrations..." +bundle exec rake data:migrate + +# Run seeds +echo "Running seeds..." +bundle exec rake db:seed + +# Precompile assets +if [ "$RAILS_ENV" = "production" ]; then + echo "Precompiling assets..." + bundle exec rake assets:precompile +fi + +# run passed commands +bundle exec ${@} diff --git a/prod-docker-entrypoint.sh b/prod-docker-entrypoint.sh deleted file mode 100644 index 52bac19a..00000000 --- a/prod-docker-entrypoint.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -unset BUNDLE_PATH -unset BUNDLE_BIN - -set -e - -echo "Environment: $RAILS_ENV" - -# set env var defaults -DATABASE_HOST=${DATABASE_HOST:-"dawarich_db"} -DATABASE_PORT=${DATABASE_PORT:-5432} -DATABASE_USERNAME=${DATABASE_USERNAME:-"postgres"} -DATABASE_PASSWORD=${DATABASE_PASSWORD:-"password"} -DATABASE_NAME=${DATABASE_NAME:-"dawarich_production"} - -# Remove pre-existing puma/passenger server.pid -rm -f $APP_PATH/tmp/pids/server.pid - -# Wait for the database to be ready -until nc -zv $DATABASE_HOST ${DATABASE_PORT:-5432}; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 -done - -# Install gems -gem update --system 3.5.23 -gem install bundler --version '2.5.21' - -# Create the database -if [ "$(psql "postgres://$DATABASE_USERNAME:$DATABASE_PASSWORD@$DATABASE_HOST:$DATABASE_PORT" -XtAc "SELECT 1 FROM pg_database WHERE datname='$DATABASE_NAME'")" = '1' ]; then - echo "Database $DATABASE_NAME already exists, skipping creation..." -else - echo "Creating database $DATABASE_NAME..." - bundle exec rails db:create -fi - -# Run database migrations -echo "PostgreSQL is ready. Running database migrations..." -bundle exec rails db:prepare - -# Run data migrations -echo "Running DATA migrations..." -bundle exec rake data:migrate - -# Run seeds -echo "Running seeds..." -bundle exec rake db:seed - -# run passed commands -bundle exec ${@}