From 01077441e0ebe6f63a758ecb00973ac42327af8a Mon Sep 17 00:00:00 2001 From: Viktor Schmidt Date: Tue, 25 Jun 2024 18:47:01 +0200 Subject: [PATCH 1/4] Add Dev Containers Docker Development Environment --- .devcontainer/.psqlrc | 32 ++++++++++++++ .devcontainer/Dockerfile | 44 +++++++++++++++++++ .devcontainer/compose.yaml | 77 +++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 30 +++++++++++++ .dockerignore | 6 +++ Aptfile.dev | 7 +++ README.md | 15 ++++++- docs/development_environment.md | 62 ++++++++++++++++++++++++++ 8 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/.psqlrc create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/compose.yaml create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 Aptfile.dev create mode 100644 docs/development_environment.md diff --git a/.devcontainer/.psqlrc b/.devcontainer/.psqlrc new file mode 100644 index 0000000..612fa5e --- /dev/null +++ b/.devcontainer/.psqlrc @@ -0,0 +1,32 @@ +-- Don't display the "helpful" message on startup. +\set QUIET 1 + +-- Allow specifying the path to history file via `PSQL_HISTFILE` env variable +-- (and fallback to the default $HOME/.psql_history otherwise) +\set HISTFILE `[ -z $PSQL_HISTFILE ] && echo $HOME/.psql_history || echo $PSQL_HISTFILE` + +-- Show how long each query takes to execute +\timing + +-- Use best available output format +\x auto + +-- Verbose error reports +\set VERBOSITY verbose + +-- If a command is run more than once in a row, +-- only store it once in the history +\set HISTCONTROL ignoredups +\set COMP_KEYWORD_CASE upper + +-- By default, NULL displays as an empty space. Is it actually an empty +-- string, or is it null? This makes that distinction visible +\pset null '[NULL]' + +\encoding unicode +\set PROMPT1 '%n@%M:%>%x %/# ' +\set PROMPT2 '' + +\setenv PAGER 'less -S' + +\unset QUIET diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..bfa14be --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,44 @@ +# See here for image contents: https://github.com/devcontainers/images/blob/main/src/ruby/.devcontainer/Dockerfile + +# [Choice] Ruby version (use -bookworm variants on local arm64/Apple Silicon): 3, 3.2, 3.1, 3.0, 3-bookworm, 3.2-bookworm, 3.1-bookworm, 3-bullseye, 3.2-bullseye, 3.1-bullseye, 3.0-bullseye, 3-buster, 3.2-buster 3.1-buster, 3.0-buster +ARG RUBY_VERSION=3 +FROM mcr.microsoft.com/devcontainers/ruby:${RUBY_VERSION}-bookworm + +# borrowed some ideas from https://github.com/evilmartians/ruby-on-whales +# LABEL maintainer="Name " + +SHELL ["/bin/bash", "-eo", "pipefail", "-c"] + +# Add PostgreSQL APT repository +RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - +RUN echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list + +COPY ../Aptfile.dev /tmp/Aptfile.dev +RUN apt-get update -qq && export DEBIAN_FRONTEND=noninteractive \ + && grep -Ev "^ *#" /tmp/Aptfile.dev | xargs apt-get install --no-install-recommends -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Set the app working directory +WORKDIR /app + +# Add the Rails main Gemfile and install the gems. This means the gem install can be done +# during build instead of on start. When a fork or branch has different gems, we still have an +# advantage due to caching of the other gems. +COPY Gemfile* ./ +RUN bundle config set --global without "production" \ + && bundle install \ + && chown -R vscode:vscode /app /usr/local/rvm + +# Run binstubs without prefixing with `bin/` or `bundle exec` +ENV PATH /app/bin:$PATH + +# Expose port 3000 to the Docker host +EXPOSE 3000 + +# Ensure binding is always 0.0.0.0 +# Binds the server to all IP addresses of the container, so it can be accessed from outside the container. +ENV BINDING="0.0.0.0" + +# Start the Rails server +CMD ["bundle", "exec", "bin/rails", "server"] diff --git a/.devcontainer/compose.yaml b/.devcontainer/compose.yaml new file mode 100644 index 0000000..0bd62d9 --- /dev/null +++ b/.devcontainer/compose.yaml @@ -0,0 +1,77 @@ +name: rideshare_devcontainer + +x-env: &default-env + RAILS_ENV: ${RAILS_ENV:-development} + RACK_ENV: ${RACK_ENV:-development} + WEB_CONCURRENCY: ${WEB_CONCURRENCY:-1} + RAILS_MIN_THREADS: ${RAILS_MIN_THREADS:-2} + RAILS_MAX_THREADS: ${RAILS_MAX_THREADS:-3} + MALLOC_ARENA_MAX: ${MALLOC_ARENA_MAX:-2} + +x-app: &app + image: rideshare_app:0.0.1 + user: "vscode" + tty: true + stdin_open: true + build: + context: .. + dockerfile: .devcontainer/Dockerfile + args: + RUBY_VERSION: ${RUBY_VERSION:-3.2} + networks: + - default + volumes: + - ../:/app:cached + - ../log:/app/log:rw,delegated + - bundle_data:/usr/local/rvm + tmpfs: + - /app/tmp:mode=01777 + environment: &app-env + <<: *default-env + BIND: 0.0.0.0 + DATABASE_URL: postgres://${POSTGRES_USER:-owner}:${POSTGRES_PASSWORD:-postgres}@postgres:5432 + HISTFILE: /app/log/.sh_history + SOURCE_PATH: $PWD + +networks: + default: + +volumes: + bundle_data: + name: rideshare_bundle_data + postgres_data: + name: rideshare_postgres_data + +services: + app: + <<: *app + # Overrides default command so things don't shut down after the process ends. + command: sleep infinity + ports: + - "127.0.0.1:3000:3000" + environment: + <<: *app-env + depends_on: + - postgres + + postgres: + image: postgres:${POSTGRES_VERSION:-16} + restart: unless-stopped + healthcheck: + test: pg_isready -U ${POSTGRES_USER:-postgres} -h postgres + interval: 30s + timeout: 3s + retries: 3 + networks: + - default + ports: + - "127.0.0.1:5432:5432" + volumes: + - ../.devcontainer/.psqlrc:/root/.psqlrc:ro + - ../log:/var/log/postgresql:rw,delegated + - postgres_data:/var/lib/postgresql/data + environment: + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + HISTFILE: /root/log/.bash_history + PSQL_HISTFILE: /root/log/.psql_history diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..2aed6c0 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,30 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ruby +{ + "name": "rideshare", + "dockerComposeFile": "compose.yaml", + "service": "app", + "workspaceFolder": "/app", + "onCreateCommand": "git config --global --add safe.directory /app", + // Configure tool-specific properties. + "containerEnv": { + "PGHOST": "postgres", + "PGUSER": "owner", + "PGPASSWORD": "postgres", + "PGDATABASE": "rideshare_development", + "RIDESHARE_DB_PASSWORD": "postgres", + "DB_URL": "postgres://postgres:postgres@postgres:5432/postgres" + }, + "customizations": { + "codespaces": { + "openFiles": [ + "README.md" + ] + }, + "vscode": { + "extensions": [ + "Shopify.ruby-lsp" + ] + } + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8660e1e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ + +/.devcontainer + +/doc +/docs +/vendore/bundle diff --git a/Aptfile.dev b/Aptfile.dev new file mode 100644 index 0000000..a0fa998 --- /dev/null +++ b/Aptfile.dev @@ -0,0 +1,7 @@ +# PostgreSQL +libpq-dev +postgresql-client-16 +postgresql-contrib + +# Additional packages +graphviz diff --git a/README.md b/README.md index dc1fc8c..da7660c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,24 @@ [![CircleCI](https://circleci.com/gh/andyatkinson/rideshare.svg?style=svg)](https://circleci.com/gh/andyatkinson/rideshare) # 📚 High Performance PostgreSQL for Rails -Rideshare is the Rails application supporting the book "High Performance PostgreSQL for Rails" , published by Pragmatic Programmers in 2024. +Rideshare is the Rails application supporting the book "High Performance PostgreSQL for Rails" , published by Pragmatic Programmers in 2024. # Installation Prepare your development machine. +## Installation - Rideshare with DevContainers + +```bash +devcontainer build --workspace-folder . +devcontainer --workspace-folder . up +devcontainer exec --workspace-folder . db/setup.sh +devcontainer exec --workspace-folder . zsh +``` + +And continue with chapter [Run Migrations](#run-migrations). + +## Installation - Rideshare on a Mac, Ruby, PostgreSQL, Gems +
🎥 Installation - Rideshare on a Mac, Ruby, PostgreSQL, Gems
diff --git a/docs/development_environment.md b/docs/development_environment.md new file mode 100644 index 0000000..3c4090f --- /dev/null +++ b/docs/development_environment.md @@ -0,0 +1,62 @@ +# Development Environment + +## Get started with Docker + +[Docker](https://docs.docker.com/) provides a way to run applications securely isolated in a container, +packaged with all its dependencies and libraries. + +Set up your [Docker environment](https://docs.docker.com/get-started/) and run: + +```bash +docker --version +docker compose --version +``` + +## Run Services in Docker Environment + +A [Docker Compose](https://docs.docker.com/compose/compose-file/) defines all services in `.devcontainer/compose.yaml` for this app. +In order to run all servies: + +```bash +docker compose -f .devcontainer/compose.yaml up -d +``` + +## Dev Containers + +The application is configured with [devcontainers](https://code.visualstudio.com/docs/devcontainers/containers). + +[A development container](https://containers.dev/overview) defines an environment +in which you develop your application before you are ready to deploy. + +A `devcontainer.json` file in your project tells +[tools and services that support the dev container spec](https://containers.dev/supporting) +how to access (or create) a dev container with a well-defined tool and runtime stack. + +### Install Dev Containers CLI (optional) + +[This CLI](https://containers.dev/implementors/reference/) can take a `devcontainer.json` and create and configure +a dev container from it. + +```bash +brew install devcontainer +``` + +### Build and Run Dev Container + +```bash +devcontainer build --workspace-folder . +devcontainer up --workspace-folder . +``` + +### Run Rails in Dev Containers + +```bash +devcontainer exec --workspace-folder . bin/rails test +devcontainer exec --workspace-folder . bin/rails server +# or +$ devcontainer exec --workspace-folder . zsh +/app $ bin/rails test +/app $ bin/dev +``` + +When finish work, exit the workspace and run `docker stop $(docker container ls -q)`. From db390e0037f43e6b420dced7ae7597ddca087816 Mon Sep 17 00:00:00 2001 From: Viktor Schmidt Date: Wed, 3 Jul 2024 10:09:17 +0200 Subject: [PATCH 2/4] Reset readme to default book version --- README.md | 15 +-------------- docs/development_environment.md | 1 + 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index da7660c..dc1fc8c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,11 @@ [![CircleCI](https://circleci.com/gh/andyatkinson/rideshare.svg?style=svg)](https://circleci.com/gh/andyatkinson/rideshare) # 📚 High Performance PostgreSQL for Rails -Rideshare is the Rails application supporting the book "High Performance PostgreSQL for Rails" , published by Pragmatic Programmers in 2024. +Rideshare is the Rails application supporting the book "High Performance PostgreSQL for Rails" , published by Pragmatic Programmers in 2024. # Installation Prepare your development machine. -## Installation - Rideshare with DevContainers - -```bash -devcontainer build --workspace-folder . -devcontainer --workspace-folder . up -devcontainer exec --workspace-folder . db/setup.sh -devcontainer exec --workspace-folder . zsh -``` - -And continue with chapter [Run Migrations](#run-migrations). - -## Installation - Rideshare on a Mac, Ruby, PostgreSQL, Gems -
🎥 Installation - Rideshare on a Mac, Ruby, PostgreSQL, Gems
diff --git a/docs/development_environment.md b/docs/development_environment.md index 3c4090f..af918c5 100644 --- a/docs/development_environment.md +++ b/docs/development_environment.md @@ -46,6 +46,7 @@ brew install devcontainer ```bash devcontainer build --workspace-folder . devcontainer up --workspace-folder . +devcontainer exec --workspace-folder . db/setup.sh ``` ### Run Rails in Dev Containers From 0722938b5d6030ce594c1b8fcee949b8ea6ef795 Mon Sep 17 00:00:00 2001 From: Viktor Schmidt Date: Wed, 3 Jul 2024 10:16:00 +0200 Subject: [PATCH 3/4] Clearly labeling the guide as an alternative and community-submitted method. --- docs/development_environment.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/development_environment.md b/docs/development_environment.md index af918c5..305891f 100644 --- a/docs/development_environment.md +++ b/docs/development_environment.md @@ -1,5 +1,7 @@ # Development Environment +This guide provides an alternative, community-submitted method for setting up and running the Rideshare application using Dev Containers. It is not the officially supported method described in the book "High Performance PostgreSQL for Rails." + ## Get started with Docker [Docker](https://docs.docker.com/) provides a way to run applications securely isolated in a container, From 50fd57da575e2b3f932925de61b59f345271cdec Mon Sep 17 00:00:00 2001 From: Viktor Schmidt Date: Wed, 3 Jul 2024 10:33:51 +0200 Subject: [PATCH 4/4] Remove Rails specific commands from guide --- docs/development_environment.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/development_environment.md b/docs/development_environment.md index 305891f..c283768 100644 --- a/docs/development_environment.md +++ b/docs/development_environment.md @@ -51,15 +51,13 @@ devcontainer up --workspace-folder . devcontainer exec --workspace-folder . db/setup.sh ``` -### Run Rails in Dev Containers +### Run Rails Commands in Dev Containers ```bash -devcontainer exec --workspace-folder . bin/rails test -devcontainer exec --workspace-folder . bin/rails server +devcontainer exec --workspace-folder . bin/rails console # or $ devcontainer exec --workspace-folder . zsh -/app $ bin/rails test -/app $ bin/dev +/app $ bin/rails console ``` When finish work, exit the workspace and run `docker stop $(docker container ls -q)`.