Files
fridoandClaude Opus 5.5 3fe3d9bab9 Začetna predloga za Rails razvojno okolje v Dockerju
- Dockerfile na osnovi ruby:4.0.9-slim z razvojnimi orodji in
  klientom PostgreSQL iz repozitorija PGDG
- docker-compose.yml s servisoma app (Rails) in db (PostgreSQL)
- .env.example, .dockerignore in .gitignore
- README z opisom sklada in navodili za nov projekt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 11:20:47 +01:00

195 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rails + PostgreSQL + Docker – začetna predloga
Predloga za razvojno okolje Ruby on Rails v Dockerju. Vsebuje samo infrastrukturo (Docker, Compose, okoljske spremenljivke, ignore datoteke). Rails aplikacijo ustvariš znotraj kontejnerja z `rails new`, zato na računalniku ne potrebuješ nameščenega Rubyja.
## Sklad
| Komponenta | Različica | Opomba |
|---|---|---|
| Ruby | 4.0.9 | uradna slika `ruby:4.0.9-slim` (minimalen Debian) |
| Ruby on Rails | zadnja stabilna | namesti se z `gem install rails` |
| PostgreSQL | 18 (`PG_MAJOR`) | uradna slika `postgres:18`; klient iz repozitorija PGDG |
| JavaScript | importmap | privzeto v Rails 8; Node.js ni potreben (glej [Če potrebuješ Node.js](#če-potrebuješ-nodejs)) |
| Docker Compose | v2 | servisa `app` in `db` |
## Datoteke
| Datoteka | Namen |
|---|---|
| `Dockerfile` | slika za razvoj: Ruby, sistemske knjižnice (`build-essential`, `git`, `libpq-dev`, `libyaml-dev`, `pkg-config`, `postgresql-client-18`), repozitorij PGDG, uporabnik `app` (UID 1000) |
| `docker-compose.yml` | servis `app` (Rails na vratih 3000) in servis `db` (PostgreSQL) ter volumna `bundle` in `pgdata` |
| `.env.example` | predloga okoljskih spremenljivk (različica PostgreSQL in dostop do baze); kopiraš jo v `.env` |
| `.dockerignore` | v sliko ne kopira skrivnosti, `.git`, dnevnikov in začasnih datotek |
| `.gitignore` | v Git ne shrani `.env`, ključev za credentials, dnevnikov ipd. |
## Zasnova
- **Osnova je `ruby:4.0.9-slim`**, enako kot v Dockerfile, ki ga ustvari Rails. Je precej manjša od polne slike, glibc pa omogoča uporabo vnaprej prevedenih gemov (nokogiri, pg ...). Razvojna orodja, ki jih `slim` nima, so dodana z `apt-get`:
- `build-essential` in `pkg-config` za prevajanje nativnih gemov,
- `libpq-dev` za gem `pg`,
- `libyaml-dev` za gem `psych`,
- `git` za geme, nameščene iz Git repozitorijev,
- `postgresql-client-<PG_MAJOR>` za `rails dbconsole` in `db:schema:dump` v formatu SQL.
- **Klient PostgreSQL je iz uradnega repozitorija PGDG** (apt.postgresql.org), ne iz Debiana. Debian ima navadno starejšo glavno različico, `pg_dump` pa zavrne izvoz iz novejšega strežnika. Različico za strežnik (`postgres:<PG_MAJOR>`) in klient določa ena spremenljivka `PG_MAJOR` v `.env` (privzeto 18). Compose jo preda Dockerfile kot build argument. Po spremembi `PG_MAJOR` zgradi sliko znova (`docker compose build`). Pri prehodu na novo glavno različico strežnika obstoječi podatki v volumnu `pgdata` niso združljivi, zato jih je treba izvoziti in uvoziti (ali volume izbrisati).
- **Geme hrani volume `bundle`**, ki je priklopljen na `/usr/local/bundle`. To je `GEM_HOME` uradne Ruby slike in je že v `PATH`. `gem install` in `bundle install` zato pišeta v isto mapo, gemi pa se ohranijo med zagoni kontejnerja.
- **`BUNDLE_PATH` namenoma ni nastavljen.** Z njim bi `bundle install` geme nameščal v drugo mapo kot `gem install`, izvršljive datoteke (`rails`, `rake`) pa ne bi bile v `PATH`.
- **Kontejner teče kot uporabnik `app` (UID 1000)**, zato so datoteke, ki jih ustvari (npr. `rails new`, migracije), na računalniku v lasti tvojega uporabnika. Če ima tvoj uporabnik drug UID (preveri z `id -u`), ga spremeni v `Dockerfile` in v `docker-compose.yml` (`user:`).
- **Koda je priklopljena z `.:/app`**, zato se spremembe takoj vidijo v kontejnerju, brez ponovne gradnje slike.
- **Podatke baze hrani volume `pgdata`**, zato ostanejo tudi po `docker compose down`.
## Nov projekt iz predloge
### 1. Kopiraj predlogo
```bash
git clone <url-predloge> moj-projekt
cd moj-projekt
rm -rf .git && git init
```
### 2. Nastavi okoljske spremenljivke
```bash
cp .env.example .env
```
V `.env` vpiši ime baze, uporabnika in geslo. `APP_DATABASE_HOST` naj ostane `db` (ime servisa v Compose).
### 3. Zgradi sliko in namesti Rails
```bash
docker compose build
docker compose run --rm app gem install rails
```
### 4. Ustvari Rails aplikacijo
```bash
docker compose run --rm app rails new . --database=postgresql --skip-docker
```
- `--skip-docker` prepreči, da bi Rails ustvaril svoj (produkcijski) `Dockerfile` in prepisal obstoječega.
- Ko vpraša, ali naj prepiše `.gitignore`, odgovori `n`. Če želiš, iz Rails-ove različice ročno dodaj manjkajoče vrstice.
- Ko vpraša, ali naj prepiše `README.md`, odgovori `n`, sicer izgubiš ta navodila. Navodila za aplikacijo lahko pozneje dopišeš sem.
### 5. Poveži Rails z bazo
V `config/database.yml` razdelek `development` nastavi na okoljske spremenljivke:
```yaml
development:
<<: *default
database: <%= ENV["APP_DATABASE"] %>
host: <%= ENV["APP_DATABASE_HOST"] %>
port: <%= ENV["APP_DATABASE_PORT"] %>
username: <%= ENV["APP_DATABASE_USERNAME"] %>
password: <%= ENV["APP_DATABASE_PASSWORD"] %>
```
Razdelek `test` nastavi enako, le z drugim imenom baze (npr. `<%= ENV["APP_DATABASE"] %>_test`).
### 6. Ustvari bazo in zaženi aplikacijo
```bash
docker compose run --rm app bin/rails db:prepare
docker compose up
```
Aplikacija je dosegljiva na <http://localhost:3000>.
### 7. Odkomentiraj namestitev gemov v Dockerfile
Ko obstajata `Gemfile` in `Gemfile.lock`, v `Dockerfile` odkomentiraj:
```dockerfile
COPY --chown=app:app Gemfile Gemfile.lock ./
RUN bundle install
```
Ob gradnji slike se tako namestijo gemi, Docker pa to plast shrani v predpomnilnik.
## Pogosti ukazi
| Opravilo | Ukaz |
|---|---|
| Zagon | `docker compose up` |
| Zagon v ozadju | `docker compose up -d` |
| Ustavitev | `docker compose down` |
| Rails konzola | `docker compose run --rm app bin/rails console` |
| Migracije | `docker compose run --rm app bin/rails db:migrate` |
| Generator | `docker compose run --rm app bin/rails generate model Company name:string` |
| Testi | `docker compose run --rm app bin/rails test` |
| Lupina v kontejnerju | `docker compose run --rm app bash` |
| Konzola PostgreSQL | `docker compose exec db psql -U <uporabnik> <baza>` |
| Dnevnik | `docker compose logs -f app` |
Če aplikacija že teče (`docker compose up`), lahko namesto `run --rm` uporabiš `exec`, ki ukaz izvede v obstoječem kontejnerju.
## Dodajanje gemov
```bash
docker compose run --rm app bundle add <ime_gema>
```
Po ročni spremembi `Gemfile`:
```bash
docker compose run --rm app bundle install
```
Volume `bundle` prekrije geme, nameščene ob gradnji slike. Po spremembi `Gemfile` zato vedno poženi `bundle install` v kontejnerju; samo ponovna gradnja slike ni dovolj.
## Če potrebuješ Node.js
Privzeti Rails 8 projekt Node.js ne potrebuje: JavaScript se naloži prek **importmap**, sredstva obdela **Propshaft**. Tudi Tailwind (`--css=tailwind`) in Dart Sass (`dartsass-rails`) uporabljata samostojni izvršljivi datoteki brez npm.
Node.js je potreben, če pri `rails new` izbereš:
- `--javascript=esbuild`, `rollup` ali `webpack` (jsbundling-rails),
- `--css=bootstrap`, `bulma`, `postcss` ali `sass` (cssbundling-rails),
ali če uporabljaš knjižnice, ki jih je treba prevesti (npr. React z JSX).
Paket `nodejs` iz Debiana za to ne zadošča, ker ne vsebuje npm in je pogosto zastarel. Node.js raje prekopiraj iz uradne slike (pred vrstico `USER app`):
```dockerfile
COPY --from=node:24-slim /usr/local/bin/node /usr/local/bin/
COPY --from=node:24-slim /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
```
Različico (`24`) izberi glede na aktualni LTS. Če potrebuješ yarn, dodaj še `RUN npm install -g yarn` (prav tako pred `USER app`).
## Odpravljanje težav
**`Permission denied` pri `gem install` ali `bundle install`**
Volume `bundle` je verjetno nastal s starejšo različico slike, ko je bila mapa v lasti uporabnika root. Odstrani ga in zgradi sliko znova:
```bash
docker compose down
docker volume ls # poišči <projekt>_bundle
docker volume rm <projekt>_bundle
docker compose build
```
**`could not translate host name "db"` ali `connection refused`**
Preveri, da je v `.env` nastavljeno `APP_DATABASE_HOST=db` in da teče servis baze (`docker compose ps`). Ob prvem zagonu PostgreSQL potrebuje nekaj sekund za inicializacijo, zato ukaz po potrebi ponovi.
**`A server is already running`**
Ostala je datoteka s PID-om strežnika:
```bash
rm tmp/pids/server.pid
```
**Ponastavitev baze od začetka**
```bash
docker compose down -v # izbriše VSE volumne, tudi podatke v bazi
```
## Opombe
- Predloga je namenjena **razvoju**. Za produkcijo uporabi Dockerfile, ki ga ustvari `rails new` (brez `--skip-docker`), ali Kamal.
- `.env` nikoli ne shranjuj v Git. V repozitorij gre samo `.env.example`.