Public Access
Template
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>
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Okoljske spremenljivke in skrivnosti
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
config/master.key
|
||||||
|
config/credentials/*.key
|
||||||
|
|
||||||
|
# Dnevniki, začasne datoteke in naložene datoteke
|
||||||
|
log/*
|
||||||
|
tmp/*
|
||||||
|
storage/*
|
||||||
|
public/assets
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
.dockerignore
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Kopiraj v .env in vpiši svoje vrednosti: cp .env.example .env
|
||||||
|
|
||||||
|
# Glavna različica PostgreSQL za strežnik in klient v kontejnerju app
|
||||||
|
PG_MAJOR=18
|
||||||
|
|
||||||
|
APP_DATABASE=poslovni_imenik_development
|
||||||
|
APP_DATABASE_HOST=db
|
||||||
|
APP_DATABASE_PORT=5432
|
||||||
|
APP_DATABASE_USERNAME=postgres
|
||||||
|
APP_DATABASE_PASSWORD=spremeni_me
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
# Okoljske spremenljivke in skrivnosti
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
/config/master.key
|
||||||
|
/config/credentials/*.key
|
||||||
|
|
||||||
|
# Dnevniki in začasne datoteke
|
||||||
|
/log/*
|
||||||
|
/tmp/*
|
||||||
|
!/log/.keep
|
||||||
|
!/tmp/.keep
|
||||||
|
/tmp/pids/*
|
||||||
|
!/tmp/pids/.keep
|
||||||
|
|
||||||
|
# Naložene datoteke (Active Storage)
|
||||||
|
/storage/*
|
||||||
|
!/storage/.keep
|
||||||
|
|
||||||
|
# Prevedena sredstva
|
||||||
|
/public/assets
|
||||||
|
/app/assets/builds/*
|
||||||
|
!/app/assets/builds/.keep
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Urejevalniki in sistem
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Poslovni imenik
|
||||||
|
|
||||||
|
## Jezik
|
||||||
|
|
||||||
|
- Komunikacija z uporabnikom poteka v **slovenskem jeziku**.
|
||||||
|
- Vsi komentarji v kodi, README datoteke in ostala dokumentacija so v **slovenskem jeziku**.
|
||||||
|
- Imena spremenljivk, funkcij, razredov in ostalih identifikatorjev v kodi so v **angleškem jeziku**.
|
||||||
|
|
||||||
|
## Izrazoslovje
|
||||||
|
|
||||||
|
- Za Docker container uporabljaj izraz **kontejner** (kontejnerja, kontejnerju ...), ne prevoda "vsebnik".
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
FROM ruby:4.0.9-slim
|
||||||
|
|
||||||
|
# Geme namešča v GEM_HOME slike (/usr/local/bundle), kjer je tudi volume "bundle"
|
||||||
|
ENV BUNDLE_JOBS=4 \
|
||||||
|
BUNDLE_RETRY=3
|
||||||
|
|
||||||
|
# Glavna različica PostgreSQL; mora se ujemati s strežnikom (nastavi jo docker-compose.yml)
|
||||||
|
ARG PG_MAJOR=18
|
||||||
|
|
||||||
|
# Uradni repozitorij PostgreSQL (PGDG), da je klient iste različice kot strežnik
|
||||||
|
RUN apt-get update -y && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
&& install -d /usr/share/postgresql-common/pgdg \
|
||||||
|
&& curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
|
||||||
|
https://www.postgresql.org/media/keys/ACCC4CF8.asc \
|
||||||
|
&& . /etc/os-release \
|
||||||
|
&& echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt ${VERSION_CODENAME}-pgdg main" \
|
||||||
|
> /etc/apt/sources.list.d/pgdg.list \
|
||||||
|
&& apt-get update -y && apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
libpq-dev \
|
||||||
|
libyaml-dev \
|
||||||
|
pkg-config \
|
||||||
|
postgresql-client-${PG_MAJOR} \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Uporabnik app mora imeti pravico pisanja v mapo z gemi
|
||||||
|
RUN useradd -u 1000 -m app \
|
||||||
|
&& chown -R app:app /usr/local/bundle
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN chown app:app /app
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
# Odkomentiraj, ko bo obstajal Gemfile (po rails new)
|
||||||
|
#COPY --chown=app:app Gemfile Gemfile.lock ./
|
||||||
|
#RUN bundle install
|
||||||
|
|
||||||
|
COPY --chown=app:app . .
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
# 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`.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
user: "1000:1000"
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
PG_MAJOR: ${PG_MAJOR:-18}
|
||||||
|
command: bin/rails server -b 0.0.0.0 -p 3000
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
RAILS_ENV: development
|
||||||
|
APP_DATABASE: ${APP_DATABASE}
|
||||||
|
APP_DATABASE_HOST: ${APP_DATABASE_HOST}
|
||||||
|
APP_DATABASE_PORT: ${APP_DATABASE_PORT}
|
||||||
|
APP_DATABASE_USERNAME: ${APP_DATABASE_USERNAME}
|
||||||
|
APP_DATABASE_PASSWORD: ${APP_DATABASE_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
- bundle:/usr/local/bundle
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:${PG_MAJOR:-18}
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${APP_DATABASE}
|
||||||
|
POSTGRES_USER: ${APP_DATABASE_USERNAME}
|
||||||
|
POSTGRES_PASSWORD: ${APP_DATABASE_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
bundle:
|
||||||
Reference in New Issue
Block a user