Skip to content

Installation avec docker

Il s'agit de la méthode la plus simple et rapide à faire.

L'image est disponible sur docker hub

Variables d'environnements à définir :

  • front :

    • NUXT_API_PARTY_ENDPOINTS_LOCAL_API_URL : Url vers l'api. Non exposé par défaut.
      • Utilisation du dns de docker : http://php
    • NUXT_SESSION_PASSWORD : Chaine aléatoire
  • php :

    • SERVER_NAME
    • MERCURE_PUBLISHER_JWT_KEY
    • MERCURE_SUBSCRIBER_JWT_KEY
    • TRUSTED_PROXIES
    • TRUSTED_HOSTS
    • DATABASE_URL
    • JWT_PASSPHRASE
    • EXPOSE_VERSION: Bool, optionnel
  • database :

    • POSTGRES_DB
    • POSTGRES_PASSWORD
    • POSTGRES_USER

Docker compose

Voici un exemple de docker-compose pour faire fonctionner le projet (backend + frontend).

yaml
name: narvik

services:

  front:
    image: benoitvignal/narvik-front:1
    restart: unless-stopped
    environment:
      # Local container (backend)
      NUXT_API_PARTY_ENDPOINTS_LOCAL_API_URL: http://php
      NUXT_SESSION_PASSWORD: 66de112769b279bceb5c7afb761b2514
      # API is hosted on a local network with self-sign certificate, and publicly accessible
      # NODE_TLS_REJECT_UNAUTHORIZED: 0

    ports:
      - 80:3000
    depends_on:
      - php
    networks:
      - narvik

  php:
    image: benoitvignal/narvik-back:1
    restart: unless-stopped
    environment:
      SERVER_NAME: php:80
      MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      TRUSTED_PROXIES: '*'
      TRUSTED_HOSTS: '*'
      DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
      # Generate a long random string
      JWT_PASSPHRASE: ffc6e86dc4456s303d11764fc6e66a46146adc1f7206eda69993a460232555be
    networks:
      - narvik
    volumes:
      - app_jwt:/app/config/jwt
      - app_private:/app/private
      - caddy_data:/data
      - caddy_config:/config

  database:
    image: postgres:${POSTGRES_VERSION:-15}-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-app}
      # You should definitely change the password in production
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!}
      POSTGRES_USER: ${POSTGRES_USER:-app}
    networks:
      - narvik
    volumes:
      - database_data:/var/lib/postgresql/data:rw
      # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
      # - ./docker/db/data:/var/lib/postgresql/data:rw
    # Database port for local debugging
    # ports:
    #   - 5432:5432




volumes:
  app_jwt:
  app_private:

  caddy_data:
  caddy_config:

  database_data:

networks:
  narvik:
    driver: bridge

Docker compose + Traefik

Pour une meilleure flexibilité, il est recommandé de séparer le docker lié à Traefik du docker liée au projet.

Cela permettra plus tard d'ajouter facilement d'autre projet, par exemple Odoo pour la gestion comptable et gestion de stock.

Les conteneurs accessibles publiquement devront être sur le network traefik-global-proxy

Dans le cas où vous copiez les configurations suivantes, des variables d'environnement global ont été définis (sudo nano /etc/environment) :

  • NARVIK_SESSION_PASSWORD
  • NARVIK_POSTGRES_DB
  • NARVIK_POSTGRES_PASSWORD
  • NARVIK_POSTGRES_USER
  • NARVIK_JWT_PASSPHRASE
  • NARVIK_CADDY_MERCURE_JWT_SECRET

Configuration de Traefik

yaml
version: "3.6" # important, so that we can name our network

services:
  traefik:
    image: "traefik:v2.11"
    container_name: "traefik"
    networks:
      - traefik-global-proxy
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - "./traefik.toml:/etc/traefik/traefik.toml"
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    # Enable for debugging  
    # labels:
    #   - "traefik.enable=true" # enable the dashboard
    #   - "traefik.http.routers.traefik.rule=Host(`<monitor domain>`)" # domain for dashboard
    #   - "traefik.http.routers.traefik.entrypoints=websecure"
    #   - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
    #   - "traefik.http.routers.traefik.service=api@internal" # points to dashboard

# this is the network that every container should connect to, in order to communicate with Traefik. We give it a nice name to type it easier.
networks:
  traefik-global-proxy:
    name: "traefik-global-proxy"
toml
[log]
  level = "ERROR"

[entryPoints]
  [entryPoints.web]
    address = ":80"

  [entryPoints.web.http.redirections.entryPoint]
    to = "websecure"
    scheme = "https"

  [entryPoints.websecure]
    address = ":443"

[certificatesResolvers.letsencrypt.acme]
  email = "<youremail>"
  storage = "/letsencrypt/acme.json"
  [certificatesResolvers.letsencrypt.acme.tlsChallenge]

[api]
  dashboard = false

[providers.docker]
  exposedByDefault = false
  network = "traefik-global-proxy" # this is really important when you have multiple networks on a single container. This will tell Traefik to always look for network traefik-global-proxy and not any other internal networks.

[http.services]
  [http.services.narvik.loadBalancer]

Dans traefik.toml, il faut définir une adresse mail valide pour la génération des certificats Let's Encrypt.

Configuration du projet

Pensez à bien définir le nom de domain dans compose.yaml à la ligne 21

yaml
version: "3.6"
name: narvik

services:

  front:
    image: benoitvignal/narvik-front:1
    restart: unless-stopped
    environment:
      NUXT_API_PARTY_ENDPOINTS_LOCAL_API_URL: http://php
      NUXT_SESSION_PASSWORD: ${NARVIK_SESSION_PASSWORD:-66de112769b279bceb5c7afb761b2514}
      # We are on a local network with self-sign certificate
      # NODE_TLS_REJECT_UNAUTHORIZED: 0
    depends_on:
      - php
    networks:
      - backend
      - traefik-global-proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.narvik.rule=Host(`<domain>`)" # domain to expose on
      - "traefik.http.routers.narvik.entrypoints=websecure" # if you named your 443 entrypoint differently than webscure, substitute it here!
      - "traefik.http.routers.narvik.tls.certresolver=letsencrypt" # if you named your cert resolver differently than letsencrypt, substitute it here!
      - "traefik.http.services.narvik.loadbalancer.server.port=3000"

  php:
    image: benoitvignal/narvik-back:1
    restart: unless-stopped
    environment:
      SERVER_NAME: php:80
      MERCURE_PUBLISHER_JWT_KEY: ${NARVIK_CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      MERCURE_SUBSCRIBER_JWT_KEY: ${NARVIK_CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
      TRUSTED_PROXIES: '*'
      TRUSTED_HOSTS: '*'
      DATABASE_URL: postgresql://${NARVIK_POSTGRES_USER:-app}:${NARVIK_POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${NARVIK_POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
      JWT_PASSPHRASE: ffc6e86d3f3f56303d11764fc6e66a46146adc1f7206eda69993a460232555be
    volumes:
      - app_jwt:/app/config/jwt
      - app_private:/app/private
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - backend

  database:
    image: postgres:${POSTGRES_VERSION:-15}-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${NARVIK_POSTGRES_DB:-app}
      # You should definitely change the password in production
      POSTGRES_PASSWORD: ${NARVIK_POSTGRES_PASSWORD:-!ChangeMe!}
      POSTGRES_USER: ${NARVIK_POSTGRES_USER:-app}
    volumes:
      - database_data:/var/lib/postgresql/data:rw
    networks:
      - backend


volumes:
  app_jwt:
  app_private:

  caddy_data:
  caddy_config:

  database_data:


networks:
  traefik-global-proxy:
    external: true
  backend:

Mise à jour

Pour effectuer les mises à jour, il suffit :

  1. Modifier la version des images dans le compose.yaml
  2. docker compose pull
  3. docker compose stop && docker compose up -d
    • La mise à jour de la base de données sera importée automatiquement au redémarrage du docker
shell
echo "🔀 Pulling latest images"
docker compose pull

echo "⚡️ Stopping docker"
docker compose stop

echo "🚀 Starting docker"
docker compose up -d

echo "✔ Docker running"