# Installation mit Docker

Plazello lässt sich als Container zusammen mit einer Datenbank betreiben. Das Installationspaket läuft im Container unverändert – derselbe Start mit `node server.js` wie auf einem Webhosting. Voraussetzung ist ein Server mit Docker und Docker Compose; prüfen Sie außerdem die [Voraussetzungen](doc:voraussetzungen).

## 1. Dateien vorbereiten

Legen Sie auf dem Server einen Ordner an, zum Beispiel `plazello-docker`, und entpacken Sie das Installationspaket darin in den Unterordner `plazello` (der Ordner, der `server.js` enthält). Daneben legen Sie die folgenden drei Dateien an.

**`Dockerfile`**

```
FROM node:24-bookworm-slim
ENV NODE_ENV=production PORT=3000 DATA_DIR=/data
WORKDIR /app
COPY plazello/ /app/
RUN mkdir -p /data && chown -R node:node /data /app
USER node
VOLUME ["/data"]
EXPOSE 3000
CMD ["node", "server.js"]
```

**`docker-compose.yml`** (mit MariaDB)

```
services:
  app:
    build: .
    environment:
      DATABASE_URL: mariadb://plazello:${DB_PASSWORD:?set DB_PASSWORD}@db:3306/plazello
      # optional: PUBLIC_URL: https://shop.example.com
    ports: ["3000:3000"]
    volumes: [data:/data]
    depends_on:
      db: { condition: service_healthy }
    restart: unless-stopped

  db:
    image: mariadb:11.4
    environment:
      MARIADB_DATABASE: plazello
      MARIADB_USER: plazello
      MARIADB_PASSWORD: ${DB_PASSWORD:?set DB_PASSWORD}
      MARIADB_RANDOM_ROOT_PASSWORD: "1"
    volumes: [db:/var/lib/mysql]
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 5s
      retries: 30
    restart: unless-stopped

volumes:
  data:
  db:
```

**`.env`** (im selben Ordner, für Docker Compose)

```
DB_PASSWORD=ein-langes-zufaelliges-passwort
```

Statt MariaDB können Sie auch MySQL 8 oder PostgreSQL 14+ verwenden. Passen Sie dann den Datenbank-Dienst an und lassen Sie `DATABASE_URL` mit `mysql://` bzw. `postgres://` beginnen.

## 2. Starten

```
docker compose up -d --build
```

Beim ersten Start legt der Shop die Datenbanktabellen an; das dauert etwa eine halbe Minute. Den **Installations-Code** für den Web-Installer finden Sie im Protokoll:

```
docker compose logs app
```

## 3. Web-Installer

Öffnen Sie `http://<Server>:3000` im Browser. Weil die Datenbank bereits über `DATABASE_URL` festgelegt ist, überspringt der Installer den Datenbank-Schritt: Sie geben nur noch den Installations-Code, den Shop-Namen und Ihr Inhaber-Konto ein. Details unter [Der Web-Installer](doc:web-installer).

## 4. HTTPS

Stellen Sie einen Reverse Proxy mit HTTPS vor den Container, zum Beispiel Caddy:

```
shop.example.com {
  reverse_proxy localhost:3000
}
```

Soll der Shop nur über den Proxy erreichbar sein, binden Sie den Port an die lokale Adresse (`ports: ["127.0.0.1:3000:3000"]`).

## Das Datenvolume

Alles, was der Shop selbst schreibt, liegt im Volume **`/data`**: der automatisch erzeugte Schlüssel zur Verschlüsselung gespeicherter Zugangsdaten, hochgeladene Bilder und Dateien (bei lokalem Speicher), Protokolle und per Update installierte Versionen. Das Volume muss deshalb immer eingebunden sein – ohne es gehen diese Daten verloren, sobald der Container neu erstellt wird. Sichern Sie es zusammen mit der Datenbank, siehe [Backups und Umzug](doc:backups-und-umzug).

## Updates

Auch im Container aktualisiert sich der Shop mit einem Klick unter **Einstellungen → Lizenz & Updates**. Die neue Version wird im Volume `/data` abgelegt und gestartet, das Image bleibt unverändert. Alternativ ersetzen Sie den Inhalt des Ordners `plazello` durch ein neueres Installationspaket und bauen neu mit `docker compose up -d --build`. Es startet immer die neuere der beiden Versionen – die per Klick installierte oder die im Image enthaltene. Mehr dazu unter [Updates installieren](doc:updates-installieren).

## Nützliche Befehle

| Befehl | Zweck |
|---|---|
| `docker compose logs -f app` | Protokoll des Shops verfolgen |
| `docker compose restart app` | Shop neu starten |
| `docker compose down` | Container stoppen (Volumes bleiben erhalten) |
| `docker compose up -d --build` | nach einem Austausch des Installationspakets neu bauen und starten |
