Thibault Mocellin

Thibault Mocellin

Développeur Full-Stack freelance basé à Annecy 🇫🇷

Créer une application web avec Docker, Parse et Next.js - Partie 6 : Déploiement Digital Ocean

Posted on June 2, 2017

Cet article est le dernier de la série qui a pour but de créer une application web qui repose sur Docker. Dans cet article nous allons déployer notre application sur Digital Ocean.

Comme il était indiqué dans le premier article de la série notre application sera accessible via le domaine jfds.fr et en https. Pour ce faire nous devrons rajouter à notre configuration actuelle un reverse proxy NGINX et générer des certificats Let’s Encrypt.

Pour cet article vous aurez donc besoin d’un domaine du fournisseur que vous souhaitez ainsi qu’un compte chez Digital Ocean. Si vous ne possédez pas de compte cher Digital Ocean vous pouvez utiliser ce lien pour vous inscrire et vous bénéficierez de 100$ de crédits.

Rappel des informations :

  • Domaine utilisé : jfds.fr
  • Fournisseur : OVH
  • Domaine Parse Server : api.jfds.fr
  • Domaine Parse Dashboard : dashboard.jfds.fr
  • Domaine application Next : jfds.fr

Création de la droplet Digital Ocean

Pour commencer nous allons créer notre droplet sur Digital Ocean

Connectez vous sur le site et cliquez sur “Create Droplet”

digital ocean droplet

Ensuite sélectionner “One-click apps” puis “Docker 17.05.0-ce on 16.04”

digital ocean droplet docker

Concernant la taille choisissez de préférence la deuxième offre.

digital ocean droplet docker

Pour finir nommez la droplet de la manière que vous voulez, cliquez sur “Create”. Quelques secondes plus tard votre droplet sera créée.

Activation IP Flottante

Une fois que votre droplet est créée, activez l’option ip flottante. Sélectionnez votre droplet dans la liste et cliquez sur “Floating IP: Enable now”

next-js docker

Puis sélectionnez votre droplet et cliquez sur “Assign Floating IP”

ditial ocean parse server

Lors de la création d’une droplet cette dernière est accessible via une adresse IP qui lui est propre. L’adresse IP flottante va vous permettre d’avoir un adresse IP qui ne changera pas peut importe l’adresse IP de la droplet.

Cela nous permet donc de configurez notre DNS pour qu’il pointe sur l’adresse IP flottante et non l’adresse IP de la droplet. Grace à ça si nous souhaitons supprimer la droplet pour en recréer une nouvelle, nous aurons juste à lui réassigner l’adresse IP flottante et la configuration DNS sera toujours valide même si l’adresse IP de la droplet a changée.

Configuration DNS

Maintenant que nous avons créé notre droplet nous allons configurer le DNS du domaine. Les étapes suivantes seront effectuées sur OVH mais le principe est le même pour les autres fournisseurs et vous devrez changer les valeurs des domaines et sous domaines par les vôtres.

Rendez vous dans l’onglet Zone DNS de votre domaine et cliquez sur “Ajouter une entrée”

ovh

Dans le champ “Option de pointage” sélectionnez A.

ovh

La première zone que nous allons ajoutez est celle de jfds.fr

Puisque pour celle ci nous ne souhaitons pas de sous domaine, nous laissons le champ Sous domaine vide, le champ TTL prend la valeur par défaut et enfin dans le champ cible nous mettons la valeur de l’adresse IP flottante de Digital Ocean.

zone dns jfds

Nous répétons l’opération pour api.jfds.fr et pour dashboard.jfds.fr

zon dns api jfds

zone dns dashboard jfds

NGINX & Let’s Encrypt

Passons à l’ajout de NGINX et Let’s Encrypt. Pour NGINX nous allons utiliser nginx-proxy. Cette image utilise les événements docker et l’api d’inspection pour générer automatiquement des configurations de reverse-proxy pour NGINX à chaque fois qu’un container est démarré. Enfin pour Let’s encrypt nous allons utiliser docker-letsencrypt-nginx-proxy-companion. Cela permet au container de se connecter directement au container NGINX et ajoutez les certificats pour les sites générés.

Nous allons ajoutez ces deux services à notre configuration Docker actuelle dans le fichier docker-compose.yml à la suite des services existants ajoutez le code suivant :

nginx-proxy:
  image: jwilder/nginx-proxy
  container_name: nginx-proxy
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - /etc/nginx/vhost.d
    - /usr/share/nginx/html
    - /apps/web/ssl:/etc/nginx/certs:ro
ssl-companion:
  image: jrcs/letsencrypt-nginx-proxy-companion
  container_name: ssl-companion
  volumes:
    - /apps/web/ssl:/etc/nginx/certs:rw
    - /var/run/docker.sock:/var/run/docker.sock:ro
  volumes_from:
    - nginx-proxy
  depends_on:
    - nginx-proxy

Ensuite il faut rajouter les trois variables d’environnement suivantes pour chaque service afin de configurer nginx-proxy et ssl-companion correctement.

  • VIRTUAL_HOST
  • LETSENCRYPT_HOST
  • LETSENCRYPT_EMAIL‍

Service api :

VIRTUAL_HOST: 'api.jfds.fr'
LETSENCRYPT_HOST: 'api.jfds.fr'
LETSENCRYPT_EMAIL: 'contact@dwastudio.fr'

Service dashboard :

VIRTUAL_HOST: 'dashboard.jfds.fr'
LETSENCRYPT_HOST: 'dashboard.jfds.fr'
LETSENCRYPT_EMAIL: 'contact@dwastudio.fr'

Service web-app :

VIRTUAL_HOST: 'jfds.fr'
LETSENCRYPT_HOST: 'jfds.fr'
LETSENCRYPT_EMAIL: 'contact@dwastudio.fr'

Une fois déployé sur votre droplet les services seront directement accessibles via leurs domaines. Il faut aussi modifier les variables d’environnement de Parse ainsi que le fichier config.js de l’application Next.js.

config.js

export const PARSE_APP_ID = 'web-app-docker';
export const PARSE_SERVER_URL = 'https://api.jfds.fr/parse';

docker-compose.yml

version: '2'
services:
    mongo:
        image: mongo:3
        container_name: "mongo-db"
        volumes:
            - ./mongo/data:/db/data
        ports:
            - "27017:27017"
    api:
        build: ./parse-server
        container_name: "parse-server"
        ports:
            - "1337:1337"
        environment:
          PORT: 1337
          DATABASE_URI: mongodb://mongo:27017
          APP_ID: "web-app-docker"
          MASTER_KEY: "master"
          PARSE_MOUNT: "/parse"
          SERVER_URL: "https://api.jfds.fr/parse"
          VIRTUAL_HOST: "api.jfds.fr"
          LETSENCRYPT_HOST: "api.jfds.fr"
          LETSENCRYPT_EMAIL: "contact@dwastudio.fr"
        volumes:
            - ./parse-server/cloud:/parse/cloud
            - ./parse-server/public:/parse/public
        depends_on:
            - mongo
    dashboard:
        build: ./dashboard
        container_name: "parse-dashboard"
        environment:
            PORT: 4040
            PARSE_DASHBOARD_ALLOW_INSECURE_HTTP: "True"
            PARSE_DASHBOARD_SERVER_URL: "https://api.jfds.fr/parse"
            PARSE_DASHBOARD_MASTER_KEY: "master"
            PARSE_DASHBOARD_APP_ID: "web-app-docker"
            PARSE_DASHBOARD_APP_NAME: "Docker Web App"
            PARSE_DASHBOARD_USER_ID: "user"
            PARSE_DASHBOARD_USER_PASSWORD: "password"
            VIRTUAL_HOST: "dashboard.jfds.fr"
            LETSENCRYPT_HOST: "dashboard.jfds.fr"
            LETSENCRYPT_EMAIL: "contact@dwastudio.fr"
        ports:
            - "4040:4040"
    web-app:
        build: ./web-app
        container_name: "web-app"
        ports:
            - "3000:3000"
        environment:
            VIRTUAL_HOST: "jfds.fr"
            LETSENCRYPT_HOST: "jfds.fr"
            LETSENCRYPT_EMAIL: "contact@dwastudio.fr"
    nginx-proxy:
        image: jwilder/nginx-proxy
        container_name: nginx-proxy
        ports:
          - '80:80'
          - '443:443'
          volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
          - /etc/nginx/vhost.d
          - /usr/share/nginx/html
          - /apps/web/ssl:/etc/nginx/certs:ro
    ssl-companion:
        image: jrcs/letsencrypt-nginx-proxy-companion
        container_name: ssl-companion
        volumes:
          - /apps/web/ssl:/etc/nginx/certs:rw
          - /var/run/docker.sock:/var/run/docker.sock:ro
        volumes_from:
          - nginx-proxy
        depends_on:
          - nginx-proxy

Ensuite il ne vous reste plus qu’à vous connectez sur votre droplet via ssh, récupérer le code source et lancer la commande docker-compose up. Vous pouvez directement cloner le repo Github et remplacer les variables.

Vous pouvez retrouver le code source ici.