Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.9
ARG NODE_VERSION=22.12.0
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
Expand All @@ -26,11 +27,22 @@ ENV RAILS_ENV="production" \
# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems
# Install packages needed to build gems and Node.js
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config libyaml-dev && \
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config libyaml-dev curl && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install Node.js
ARG NODE_VERSION
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
rm -rf /tmp/node-build-master

ENV PATH=/usr/local/node/bin:$PATH

# Enable corepack for yarn/pnpm
RUN corepack enable

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
Expand Down
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ gem "jbuilder"
# Use Redis adapter to run Action Cable in production
gem "redis", "~> 5.3"

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS)
gem "rack-cors"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"

Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ GEM
nio4r (~> 2.0)
racc (1.8.1)
rack (3.2.4)
rack-cors (3.0.0)
logger
rack (>= 3.0.14)
rack-mini-profiler (4.0.1)
rack (>= 1.2.0)
rack-session (2.1.1)
Expand Down Expand Up @@ -378,6 +381,7 @@ DEPENDENCIES
jbuilder
pg (~> 1.5)
puma (~> 6.5)
rack-cors
rack-mini-profiler
rails (~> 7.2)
redis (~> 5.3)
Expand Down
17 changes: 17 additions & 0 deletions app/controllers/api/v1/health_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module Api
module V1
class HealthController < ApplicationController
skip_before_action :verify_authenticity_token

def index
render json: {
status: "ok",
message: "Rails API is running!",
timestamp: Time.current
}
end
end
end
end
17 changes: 16 additions & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,26 @@ services:
env_file:
- .env
environment:
- HISTFILE=/usr/src/app/log/.bash_history
- HISTFILE=/usr/src/app/log/.bash_history
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
frontend:
build:
context: ./
dockerfile: development.Dockerfile
command: bash -c "cd frontend && npm run dev -- --host 0.0.0.0"
volumes:
- .:/usr/src/app
- node_modules:/usr/src/app/frontend/node_modules
ports:
- "5173:5173"
environment:
- VITE_API_URL=http://localhost:3000
stdin_open: true
tty: true
db:
image: postgres:17
ports:
Expand All @@ -40,3 +54,4 @@ volumes:
pg_data:
redis_data:
bundle:
node_modules:
19 changes: 19 additions & 0 deletions config/initializers/cors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

# Be sure to restart your server when you modify this file.

# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin Ajax requests.

# Read more: https://github.com/cyu/rack-cors

Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins "localhost:5173", "127.0.0.1:5173"

resource "*",
headers: :any,
methods: [ :get, :post, :put, :patch, :delete, :options, :head ],
credentials: true
end
end
7 changes: 7 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
# Can be used by load balancers and uptime monitors to verify that the app is live.
get "up" => "rails/health#show", as: :rails_health_check

# API routes
namespace :api do
namespace :v1 do
get "health", to: "health#index"
end
end

resources :articles do
resources :comments
end
Expand Down
12 changes: 12 additions & 0 deletions development.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.9
ARG NODE_VERSION=22.12.0
FROM docker.io/library/ruby:$RUBY_VERSION-slim as base

# OS Level Dependencies
Expand All @@ -28,6 +29,17 @@ ENV LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3

# Install Node.js
ARG NODE_VERSION
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
rm -rf /tmp/node-build-master

ENV PATH=/usr/local/node/bin:$PATH

# Enable corepack for yarn/pnpm
RUN corepack enable

WORKDIR /usr/src/app

ENTRYPOINT ["./bin/docker-entrypoint-development"]
Expand Down
24 changes: 24 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
73 changes: 73 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## React Compiler

The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
23 changes: 23 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
13 changes: 13 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>rails7-on-docker</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading