-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from rahu1ramesh/BAH-4127
Add docker Compose Orchestration And Setup Guide
- Loading branch information
Showing
7 changed files
with
305 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,3 +35,4 @@ | |
|
||
/app/assets/builds/* | ||
!/app/assets/builds/.keep | ||
/vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,57 @@ | ||
# syntax=docker/dockerfile:1 | ||
# check=error=true | ||
|
||
# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: | ||
# docker build -t medispeak_backend . | ||
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name medispeak_backend medispeak_backend | ||
|
||
# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html | ||
|
||
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version | ||
ARG RUBY_VERSION=3.2.2 | ||
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base | ||
|
||
# Rails app lives here | ||
WORKDIR /rails | ||
|
||
# Install base packages | ||
RUN apt-get update -qq && \ | ||
apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \ | ||
rm -rf /var/lib/apt/lists /var/cache/apt/archives | ||
apt-get install --no-install-recommends -y \ | ||
curl libjemalloc2 libvips postgresql-client && \ | ||
apt-get clean && \ | ||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/cache/apt/archives/* | ||
|
||
# Set production environment | ||
ENV RAILS_ENV="production" \ | ||
BUNDLE_DEPLOYMENT="1" \ | ||
BUNDLE_PATH="/usr/local/bundle" \ | ||
BUNDLE_WITHOUT="development" | ||
|
||
# Throw-away build stage to reduce size of final image | ||
# Build stage for gems and precompilation | ||
FROM base AS build | ||
|
||
# Install packages needed to build gems | ||
# Install build dependencies and clean up in the same layer | ||
RUN apt-get update -qq && \ | ||
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config && \ | ||
rm -rf /var/lib/apt/lists /var/cache/apt/archives | ||
apt-get install --no-install-recommends -y \ | ||
build-essential git libpq-dev pkg-config && \ | ||
apt-get clean && \ | ||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/cache/apt/archives/* | ||
|
||
# Install application gems | ||
# Install gems and clean up after installation to save space | ||
COPY Gemfile Gemfile.lock ./ | ||
RUN bundle install && \ | ||
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ | ||
RUN bundle install --jobs=4 --retry=3 && \ | ||
rm -rf ~/.bundle/ "${BUNDLE_PATH}/ruby/*/cache" "${BUNDLE_PATH}/ruby/*/bundler/gems/*/.git" && \ | ||
bundle exec bootsnap precompile --gemfile | ||
|
||
# Copy application code | ||
# Copy application code after bundle install (for caching purposes) | ||
COPY . . | ||
|
||
# Precompile bootsnap code for faster boot times | ||
RUN bundle exec bootsnap precompile app/ lib/ | ||
|
||
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY | ||
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile | ||
# Precompile bootsnap and assets | ||
RUN bundle exec bootsnap precompile app/ lib/ && \ | ||
SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile | ||
|
||
|
||
|
||
|
||
# Final stage for app image | ||
# Final image for running the application | ||
FROM base | ||
|
||
ARG RAILS_ENV \ | ||
BUNDLE_DEPLOYMENT \ | ||
BUNDLE_PATH \ | ||
BUNDLE_WITHOUT | ||
|
||
# Copy built artifacts: gems, application | ||
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" | ||
COPY --from=build /rails /rails | ||
|
||
# Run and own only the runtime files as a non-root user for security | ||
# Run as non-root user for security | ||
RUN groupadd --system --gid 1000 rails && \ | ||
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ | ||
chown -R rails:rails db log storage tmp | ||
USER 1000:1000 | ||
USER rails:rails | ||
|
||
# Entrypoint prepares the database. | ||
# Entrypoint and default command | ||
ENTRYPOINT ["/rails/bin/docker-entrypoint"] | ||
|
||
# Start server via Thruster by default, this can be overwritten at runtime | ||
EXPOSE 80 | ||
CMD ["./bin/thrust", "./bin/rails", "server"] | ||
EXPOSE 3000 | ||
CMD ["./bin/thrust", "./bin/rails", "server"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
services: | ||
medispeak_db: | ||
image: 'postgres:${POSTGRES_IMAGE_TAG:?}' | ||
container_name: medispeak_db | ||
volumes: | ||
- medispeak_data:/var/lib/postgresql/data:rw | ||
command: postgres -c 'max_connections=500' | ||
environment: | ||
POSTGRES_DB: ${DB_NAME} | ||
POSTGRES_USER: ${DB_USERNAME} | ||
POSTGRES_PASSWORD: ${DB_PASSWORD} | ||
ports: | ||
- "${DB_PORT}:${DB_PORT}" | ||
restart: unless-stopped | ||
healthcheck: | ||
test: ["CMD", "pg_isready", "-U", "postgres"] | ||
interval: 30s | ||
timeout: 10s | ||
retries: 5 | ||
|
||
medispeak_backend: | ||
build: | ||
context: . | ||
dockerfile: Dockerfile | ||
args: | ||
RAILS_ENV: ${RAILS_ENV} | ||
BUNDLE_DEPLOYMENT: ${BUNDLE_DEPLOYMENT} | ||
BUNDLE_PATH: ${BUNDLE_PATH} | ||
BUNDLE_WITHOUT: ${BUNDLE_WITHOUT} | ||
container_name: medispeak_backend | ||
command: "bundle exec rails s -p ${BACKEND_PORT} -b '0.0.0.0'" | ||
environment: | ||
DB_HOST: ${DB_HOST} | ||
DB_NAME: ${DB_NAME} | ||
DB_USERNAME: ${DB_USERNAME} | ||
DB_PASSWORD: ${DB_PASSWORD} | ||
OPENAI_ACCESS_TOKEN: ${OPENAI_ACCESS_TOKEN} | ||
OPENAI_ORGANIZATION_ID: ${OPENAI_ORGANIZATION_ID} | ||
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} | ||
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} | ||
AWS_REGION: ${AWS_REGION} | ||
AWS_BUCKET: ${AWS_BUCKET} | ||
PLUGIN_BASE_URL: ${PLUGIN_BASE_URL} | ||
volumes: | ||
- .:/app:cached | ||
ports: | ||
- "${BACKEND_PORT}:${BACKEND_PORT}" | ||
depends_on: | ||
medispeak_db: | ||
condition: service_healthy | ||
restart: unless-stopped | ||
volumes: | ||
medispeak_data: | ||
driver: local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
# Medispeak Developer Setup Guide with Docker Compose | ||
|
||
This guide will walk you through the steps to set up the Medispeak backend using Docker Compose. The configuration includes two main services: | ||
|
||
1. **Rails Backend** (`medispeak_backend`): The main application container running the Medispeak Rails backend. | ||
2. **PostgreSQL Database** (`medispeak_db`): A database container that handles data persistence for the Medispeak application. | ||
|
||
--- | ||
|
||
## Prerequisites | ||
|
||
Before getting started, make sure you have the following installed on your local machine: | ||
|
||
1. **Docker**: For containerizing and running the services. | ||
2. **Docker Compose**: To manage the multi-container setup. | ||
|
||
Ensure Docker and Docker Compose are properly installed and running. You can verify the installation by running: | ||
|
||
```bash | ||
docker --version | ||
docker-compose --version | ||
``` | ||
|
||
## 1. Docker Compose Configuration Overview | ||
|
||
The `docker-compose.yml` file defines two main services: the PostgreSQL database (`medispeak_db`) and the Rails backend (`medispeak_backend`). | ||
|
||
### 1.1 PostgreSQL Database Configuration | ||
|
||
The `medispeak_db` service uses the official PostgreSQL image and specifies several key configurations: | ||
|
||
- **Environment Variables**: | ||
- `POSTGRES_DB`: Defines the database name. | ||
- `POSTGRES_USER`: Sets the username for the database. | ||
- `POSTGRES_PASSWORD`: Sets the password for the PostgreSQL user. | ||
- **Ports**: The container exposes the PostgreSQL port defined by `DB_PORT`. | ||
- **Volumes**: Data is persisted across container restarts using a Docker volume (`medispeak_data`). | ||
|
||
### 1.2 Medispeak Backend Configuration | ||
|
||
The `medispeak_backend` service is the core Rails application. It depends on the `medispeak_db` service being healthy before starting. Key aspects: | ||
|
||
- **Build Arguments**: The build process takes several arguments, such as `RAILS_ENV`, `BUNDLE_DEPLOYMENT`, and others for bundling gems and preparing the Rails environment. | ||
- **Environment Variables**: | ||
- OpenAI credentials (`OPENAI_ACCESS_TOKEN`, `OPENAI_ORGANIZATION_ID`). | ||
- AWS credentials for file storage (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, etc.). | ||
- PostgreSQL database connection details (`DB_HOST`, `DB_NAME`, `DB_USERNAME`, `DB_PASSWORD`). | ||
- Plugin-related configuration (`PLUGIN_BASE_URL`). | ||
- **Ports**: The Rails backend exposes the port defined by `BACKEND_PORT`. | ||
- **Volumes**: The application code is mounted inside the container using a bind mount to keep it in sync with your local development files. | ||
|
||
--- | ||
|
||
## 2. Setting Up Environment Variables | ||
|
||
Before running the services, you’ll need to configure environment variables. These variables control the behavior of both the Rails backend and PostgreSQL database. | ||
|
||
1. **Create a `.env` file** in the root directory (where the `docker-compose.yml` file is located) with the following content: | ||
|
||
```bash | ||
# OpenAI Credentials | ||
OPENAI_ACCESS_TOKEN=your_openai_access_token | ||
OPENAI_ORGANIZATION_ID=your_openai_organization_id | ||
|
||
# Plugin Configuration | ||
PLUGIN_BASE_URL=https://medispeak-app.pages.dev | ||
|
||
# Rails Environment | ||
RAILS_ENV= | ||
BUNDLE_DEPLOYMENT=1 | ||
BUNDLE_PATH="/usr/local/bundle" | ||
BUNDLE_WITHOUT="development test" | ||
BACKEND_PORT=3000 | ||
|
||
# AWS S3 Configuration (required for production) | ||
AWS_ACCESS_KEY_ID=your_aws_access_key | ||
AWS_SECRET_ACCESS_KEY=your_aws_secret_key | ||
AWS_REGION=your_aws_region | ||
AWS_BUCKET=your_s3_bucket_name | ||
|
||
# Database Configuration (Required) | ||
POSTGRES_IMAGE_TAG=14.2-alpine | ||
DB_NAME=medispeak | ||
DB_NAME_TEST=medispeak_test | ||
DB_HOST=medispeak_db | ||
DB_USERNAME=postgres | ||
DB_PASSWORD=postgres | ||
DB_PORT=5432 | ||
``` | ||
|
||
> **Note**: `RAILS_ENV` sets the environment (e.g., development, production), `BUNDLE_DEPLOYMENT` ensures only production gems install, `BUNDLE_PATH` defines the gem directory, `BUNDLE_WITHOUT` skips development/test gems, and `BACKEND_PORT` specifies the port the app runs on (default: 3000). | ||
> | ||
> **Note**: A sample `.env` file has been provided for reference and can be found in the [example.env](../example.env) file. This example will help guide the configuration process by specifying the required environment variables. Please review and adapt it as necessary to meet your project requirements. | ||
> | ||
> **Note**: Replace placeholder values (`your_openai_access_token`, `your_aws_access_key`, etc.) with actual values from your OpenAI and AWS accounts. | ||
--- | ||
|
||
## 3. Running the Application with Docker Compose | ||
|
||
After setting up the environment variables, you're ready to bring up the services. | ||
|
||
### Step-by-Step Instructions | ||
|
||
1. **Build the services**: | ||
Run the following command to build the Docker images for the services, using the configurations from the `docker-compose.yml` file: | ||
|
||
```bash | ||
docker-compose build | ||
``` | ||
|
||
2. **Start the services**: | ||
Start both the PostgreSQL and Rails backend services by running: | ||
|
||
```bash | ||
docker-compose up -d | ||
``` | ||
|
||
- The **PostgreSQL** service (`medispeak_db`) will start first. | ||
- The **Rails backend** service (`medispeak_backend`) will wait for the database to be healthy before starting. | ||
|
||
3. **Verify the setup**: | ||
- Once the services are up and running, the Rails backend will be available at `http://localhost:3000` (or on the port you’ve specified in the `.env` file as `BACKEND_PORT`). | ||
- You can check the logs for any issues or confirmations of successful setup by running: | ||
|
||
```bash | ||
docker-compose logs | ||
``` | ||
|
||
4. **Stopping the services**: | ||
To stop the services gracefully, run: | ||
|
||
```bash | ||
docker-compose down | ||
``` | ||
|
||
This command will stop the running containers and remove them, but the data in your PostgreSQL volume will remain intact for future use. | ||
|
||
--- | ||
|
||
## 4. Additional Configuration Options | ||
|
||
- **Running Migrations**: | ||
After the services are running, you may need to run database migrations: | ||
|
||
```bash | ||
docker-compose exec medispeak_backend bundle exec rails db:migrate | ||
``` | ||
|
||
- **Import Seed Data**: | ||
After the services are running, you may need to run the following command to import the seed: | ||
|
||
```bash | ||
docker-compose exec medispeak_backend bundle exec rails db:seed | ||
``` | ||
|
||
- **Accessing the Rails Console**: | ||
If you need to open the Rails console for debugging or testing, you can do so by running: | ||
|
||
```bash | ||
docker-compose exec medispeak_backend bundle exec rails console | ||
``` | ||
|
||
- **Database Health Check**: | ||
The PostgreSQL service has a health check that ensures the database is ready before the Rails backend tries to connect. You can monitor the database’s health by checking the logs: | ||
|
||
```bash | ||
docker-compose logs medispeak_db | ||
``` | ||
|
||
--- | ||
|
||
## 5. Persistent Data with Docker Volumes | ||
|
||
- The PostgreSQL container uses a Docker volume named `medispeak_data` to persist its data. This ensures that your data will be preserved even if the container is stopped or removed. | ||
|
||
- The volume configuration is defined at the bottom of the `docker-compose.yml` file: | ||
|
||
```yaml | ||
volumes: | ||
medispeak_data: | ||
driver: local | ||
``` | ||
|
||
To inspect the volume data, you can run: | ||
|
||
```bash | ||
docker volume ls | ||
``` | ||
|
||
--- | ||
|
||
## 6. Production Considerations | ||
|
||
For production deployments, ensure the following: | ||
|
||
- **AWS Credentials**: The AWS credentials in your environment variables must be set to properly manage file storage in S3. | ||
- **RAILS_MASTER_KEY**: Ensure that you provide the correct `RAILS_MASTER_KEY` for your encrypted credentials. | ||
- **Secret Management**: Consider using a secure secret management system, such as AWS Secrets Manager, for sensitive information like OpenAI tokens, AWS credentials, and database passwords. | ||
|
||
--- | ||
|
||
## Conclusion | ||
|
||
By following this guide, you can get the Medispeak backend and its PostgreSQL database up and running using Docker Compose. The environment is flexible, allowing you to adjust configurations via environment variables and scale for both development and production needs. |
Oops, something went wrong.