POC - Déployer en 5 min un blog Ghost 3 chez Scaleway
Ghost est un moteur de blog medium like, open source et écrit en JavaScript. Nous nous sommes amusés à déployer un Ghost chez Scaleway en 3 commandes avec du SSL Let's Encrypt.
Mais vous allez me dire il y a une image de Ghost dispo dans la catalogue de Scaleway !. L'idée est de faire un maximum de chose soi-même ;) ainsi, nous avons choisi d'utiliser une image Docker (dispo sur tous les services de Cloud).
Voici la listes des outils que nous avons utilisé :
- Scaleway - solution de cloud FRANÇAIS
- Terraform - provider Scaleway
- Ansible - modules apt, pip, copy, docker_network, docker_swarm et docker_stack
- Docker
- Docker Swarm
- Docker compose
- Traefik v2 (nouvelle version)
- Let's Encrypt - autorité de certification gratuite
- xip.io - "magic domain name that provides"
- mysql - backend Ghost
- Ghost 3
Tous les fichiers sont sur notre github (lien à la fin de l'article).
Prérequis
- Terraform - install
- Ansible version 2.8 - install
- Compte Scaleway et un API Token - documentation (en)
Terraform
Terraform se base sur les API des fourniseurs de service cloud et permet d'automatiser une grande quantité d'actions, création de VMs, création volume bloc storage, etc. mais aussi update ou downgrade de profile de VMs.
Files
3 fichiers :
- variable.tf : Déclaration des variables utilisés dans le main.tf, remplacer IP_ADMIN par votre ip depuis laquelle vous administrerez le serveur
- output.tf : Varialble qui s'affiche à la fin de l'exécution
- main.tf : Déscription des actions
variable.tf
variable "ipadmin" {
description = "Adresse IP d'admin"
default = "IP_ADMIN"
}
output.tf
output "Public_ip" {
value = "${scaleway_instance_server.docker.public_ip}"
}
output "Name" {
value = "${scaleway_instance_server.docker.name}"
}
main.tf Updater les informations suivantes :
- SCALEWAY_ACCESS_KEY
- SCALEWAY_SECRET_KEY
- SCALEWAY_ORGANIZATION_ID
provider "scaleway" {
access_key = "SCALEWAY_ACCESS_KEY"
secret_key = "SCALEWAY_SECRET_KEY"
organization_id = "SCALEWAY_ORGANIZATION_ID"
zone = "fr-par-1"
region = "fr-par"
}
resource "scaleway_instance_ip" "public_ip" {
server_id = "${scaleway_instance_server.docker.id}"
}
resource "scaleway_instance_security_group" "www" {
inbound_default_policy = "drop"
outbound_default_policy = "accept"
inbound_rule {
action = "accept"
port = "22"
ip = "${var.ipadmin}"
}
inbound_rule {
action = "accept"
port = "80"
}
inbound_rule {
action = "accept"
port = "443"
}
inbound_rule {
action = "accept"
port = "8080"
}
}
resource "scaleway_instance_server" "docker" {
type = "DEV1-S"
image = "89c80d27-ddf4-4ffa-8215-b335cce3fd05"
tags = [ "docker", "blog" ]
security_group_id= "${scaleway_instance_security_group.www.id}"
}
Commandes
Download des modules
terraform init
GO !
terraform apply
Et voilà, vous avez une magnifique VM qui n'attend plus que votre blog !
Ansible & Docker
Ansible est un logiciel de déploiement/configuration par SSH.
Files
- main.yml : centralise les paramètres et actions
- docker-compose.yml : fichier d'orchestration du déploiement de la stack - traefik v2 / mysql / ghost
main.yml
- hosts: all
gather_facts: False
tasks:
- name: install packages base
apt: name={{ packages }} state=present update_cache=yes state=latest
vars:
packages:
- python-pip
- name: install packages pip
pip: name={{ packages }} state=present
vars:
packages:
- docker
- pyyaml
- jsondiff
- name: Init a new swarm with default parameters
docker_swarm: state=present
- name: Create a network
docker_network: name=traefik-public driver=overlay
- name: Copy docker compose
copy: src=docker-compose.yml dest=/opt/docker-compose.yml
- name: Deploy stack from a compose file
docker_stack:
state: present
name: web
compose:
- /opt/docker-compose.yml
docker-compose.yml
- remplacer SCALEWAY_IP_PUBLIC par votre ip publique scaleway
- remplacer LETSENCRYPT_EMAIL par votre adresse qui sera référencée chez Let's Encrypt
version: "3.7"
services:
proxy:
image: "traefik:v2.0.2"
command:
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik-public"
- "--entrypoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--api.insecure"
- "--certificatesresolvers.le.acme.tlschallenge=true"
- "--certificatesresolvers.le.acme.email=LETSENCRYPT_EMAIL"
- "--certificatesresolvers.le.acme.storage=/le/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "cert:/le"
networks:
- traefik-public
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-public"
- "traefik.http.routers.admin.rule=Host(`traefik.SCALEWAY_IP_PUBLIC.xip.io`)"
- "traefik.http.routers.admin.entrypoints=websecure"
- "traefik.http.routers.admin.tls.certresolver=le"
- "traefik.http.services.admin.loadbalancer.server.port=8080"
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
blog:
image: ghost:latest
environment:
url: https://blog.SCALEWAY_IP_PUBLIC.xip.io
database__client: mysql
database__connection__host: db
database__connection__user: user
database__connection__password: example
database__connection__database: ghost
volumes:
- ghost:/var/lib/ghost/content
depends_on:
- proxy
- db
networks:
- traefik-public
- back
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-public"
- "traefik.http.routers.blog.rule=Host(`blog.SCALEWAY_IP_PUBLIC.xip.io`)"
- "traefik.http.routers.blog.entrypoints=websecure"
- "traefik.http.services.blog.loadbalancer.server.port=2368"
- "traefik.http.routers.blog.tls.certresolver=le"
db:
image: mysql:5
environment:
MYSQL_DATABASE: ghost
MYSQL_USER: user
MYSQL_PASSWORD: example
MYSQL_ROOT_PASSWORD: example
volumes:
- db:/var/lib/mysql
networks:
- back
volumes:
cert:
ghost:
db:
networks:
back:
traefik-public:
external: true
Commandes
ansible-playbook -u root -i IP_PUBLIC_SCALEWAY main.yml
YES !!
Vous passientez 5 minutes le temps que les images docker soient download et ghost initie sa base de données et :
- https://blog.SCALEWAY_IP_PUBLIC.xip.io : pour votre Ghost (/ghost pour l'admin) avec une redirection - http > https
- https://SCALEWAY_IP_PUBLIC.xip.io pour accéder au dashboard de Traefik v2
Projections & Evolutions
- xip.io est utile afin d'avoir un fqdn sans devoir faire de pointage DNS, c'est donc très partique pour les POC. Vous pouvez bien évidement utiliser votre domaine.
- Il est recommandé de sécuriser l'accès au dashboard Traefik pour de la prod (authentification ou filtrage IP).
- Scaleway propose un service de bloc storage, il serait intéressant d'implémenter ce service pour le stockage des médias du blog.
Clean - fin du POC
Pour supprimer l'instance et les configurations réalisées chez Scaleway, Terraform vous a simplfié les choses. Balancer cette commande :
terraform destroy