Git Product home page Git Product logo

docker-101's Introduction

Docker-101

Deploy a full stack with the following services:

  • Wordpress
  • Drupal
  • Database
  • Reverse Proxy

We are going to use the localhost as a domain. You can choose any reverse proxy you like. All options have the following in common:

  • .env
DOMAIN=localhost
  • init folder with a sql file
CREATE DATABASE IF NOT EXISTS `wordpress`;
CREATE DATABASE IF NOT EXISTS `drupal`;
GRANT ALL ON `wordpress`.* TO 'user'@'%';
GRANT ALL ON `drupal`.* TO 'user'@'%';
  • docker-compose.yml

Table of contents

Certificates

The certificates are required for traefik and nginx. Please follow the instruction corresponding to your distro.

On ubuntu/debian:

sudo apt-get update

sudo apt install wget libnss3-tools

curl -s https://api.github.com/repos/FiloSottile/mkcert/releases/latest| grep browser_download_url  | grep linux-amd64 | cut -d '"' -f 4 | wget -qi -

mv mkcert-v*-linux-amd64 mkcert

chmod a+x mkcert

sudo mv mkcert /usr/local/bin/

On archlinux:

sudo pacman -S nss

sudo pacman -Syu mkc

Create a directory for your certificates:

mkdir certs

Generate your certificates:

mkcert -install 

sudo mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem "localhost" "*.localhost"

Caddy

Caddy has a very simple configuration, the Caddyfile will handle the https redirection.

Caddyfile:

drupal.{$DOMAIN} {
    reverse_proxy drupal:80
}

wordpress.{$DOMAIN} {
    reverse_proxy wordpress:80
}

docker-compose.yml :

version: "3.7"
services:

  caddy:
    image: caddy
    container_name: caddy
    hostname: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config

  db:
     container_name: mysql
     image: mysql:8
     volumes:
      - db_data:/var/lib/mysql
      - ./init:/docker-entrypoint-initdb.d
     restart: always
     environment:
      MYSQL_ROOT_PASSWORD: test
      MYSQL_USER: user
      MYSQL_PASSWORD: test

  wordpress:
     depends_on:
      - db
     container_name: wordpress
     image: wordpress:5.8.2
     hostname: wordpress  
     environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: test
      WORDPRESS_DB_NAME: wordpress
     restart: always
     volumes:
      - wordpress:/var/www/html

  drupal:
    depends_on:
      - db
    container_name: drupal
    hostname: drupal
    image: drupal:9.3
    restart: always
    environment:
      DRUPAL_DB_HOST: db:3306
      DRUPAL_DB-USER: user
      DRUPAL_DB_PASSWORD: test
      DRUPAL_DB_NAME: drupal
    volumes:
       - drupal_modules:/var/www/html/modules
       - drupal_profiles:/var/www/html/profiles
       - drupal_themes:/var/www/html/themes
       - drupal_sites:/var/www/html/sites
volumes:
    wordpress:
    drupal_modules:
    drupal_profiles:
    drupal_themes:
    drupal_sites:
    db_data: {}

run:

docker-compose up -d

the links:

https://wordpress.localhost/

https://drupal.localhost/

Authentification

Caddy can enable basic authentification, which can be used to protect directories and files with a username and hashed password. We are going to use bcrypt for hash algorithmn and use base64. Here the password is admin:

<subdomain>.{$DOMAIN} {
    reverse_proxy <service>:80
    basicauth {
        admin JDJhJDA4JEtHUk44YmpSTm9oZGRHVzZNS0FWV2VGVzQwZXYxT1dCREVGdFBoZ2h2MzdwaDFYeUwyL2hT
    }
}

^ back to top ^

Nginx

WIP

^ back to top ^

Traefik

First create a traefik.yml for you static configuration:

global:
  sendAnonymousUsage: false

api:
  dashboard: true
  insecure: false

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    watch: true
    exposedByDefault: false

  file:
    filename: /etc/traefik/config.yml
    watch: true

log:
  level: INFO
  format: common

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
  https:
    address: ":443"

Then a tls.yml

http:
  routers:
    traefik:
      rule: "Host(`traefik.localhost`)"
      service: "api@internal"
      tls:
        domains:
          - main: "localhost"
            sans:
              - "*.localhost"
          - main: "domain.local"
            sans:
              - "*.domain.local"

tls:
  certificates:
    - certFile: "/etc/certs/local-cert.pem"
      keyFile: "/etc/certs/local-key.pem"

The tls.yml will handle the ssl certificates and the routing of traefik dashboard. While the traefik.yml will handle the redirection from port 80 to port 443, the activation of the dashboard and it will defines docker as a provider. This set up allow to easily add new services by just adding labels to docker-compose. Last but not least you don't to restart traefik when a new service is detected.

And like with the other proxies you need a docker-compose.yml.

version: '3'
services:
   db:
     container_name: mysql
     image: mysql:8
     volumes:
       - db_data:/var/lib/mysql
       - ./init:/docker-entrypoint-initdb.d
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: test
       MYSQL_USER: user
       MYSQL_PASSWORD: test

   wordpress:
     depends_on:
       - db
     container_name: wordpress
     image: wordpress:5.8.2
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: user
       WORDPRESS_DB_PASSWORD: test
       WORDPRESS_DB_NAME: wordpress
     restart: always
     volumes:
       - wordpress:/var/www/html
     labels:
       - "traefik.http.routers.wordpress.rule=Host(`wordpress.$DOMAIN`)"
       - "traefik.enable=true"
       - "traefik.http.routers.wordpress.tls=true"
       - "traefik/http.routers.wordpress.tls.tls.domains[0].main=wordpress.$DOMAIN"
       - "traefik/http.routers.wordpress.tls.tls.domains[0].sans=wordpress-*.$DOMAIN"

   drupal:
     depends_on:
       - db
     container_name: drupal
     image: drupal:9.3
     restart: always
     environment:
       DRUPAL_DB_HOST: db:3306
       DRUPAL_DB-USER: user
       DRUPAL_DB_PASSWORD: test
       DRUPAL_DB_NAME: drupal
     volumes:
       - drupal_modules:/var/www/html/modules
       - drupal_profiles:/var/www/html/profiles
       - drupal_themes:/var/www/html/themes
       - drupal_sites:/var/www/html/sites
     labels:  
       - "traefik.http.routers.drupal.rule=Host(`drupal.$DOMAIN`)"
       - "traefik.enable=true"
       - "traefik.http.routers.drupal.tls=true"
       - "traefik/http.routers.drupal.tls.tls.domains[0].main=drupal.$DOMAIN"
       - "traefik/http.routers.drupal.tls.tls.domains[0].sans=drupal-*.$DOMAIN
       
   reverse-proxy:
     container_name: traefik
     image: traefik:v2.5
     # Enables the web UI and tells Traefik to listen to docker
     restart: always
     command: 
       - "--providers.docker"
     ports:
       - "80:80"
       - "443:443"
     volumes:
       # So that Traefik can listen to the Docker events
       - /var/run/docker.sock:/var/run/docker.sock
       # static conf
       - ./traefik.yml:/etc/traefik/traefik.yml:ro
       # dynamic conf
       - ./tls.yml:/etc/traefik/tls.yml:ro
       # self-signed certificate
       - ./certs:/etc/certs:ro
     labels:
       - "traefik.enable=true"
       - "traefik.http.routers.traefik=true"
       - "traefik.http.routers.api.rule=Host(`traefik.${DOMAIN}`)"
       - "traefik.http.routers.api.tls.certresolver=certificato"
       - "traefik.http.routers.api.tls.domains[0].main=*.${DOMAIN}"
       - "traefik.http.routers.api.service=api@internal"       

volumes:
    wordpress:
    drupal_modules:
    drupal_profiles:
    drupal_themes:
    drupal_sites:
    db_data: {}
 

Run:

docker-compose up -d 

the links:

https://wordpress.localhost/

https://drupal.localhost/

Https is also available for homer, adminer and portainer, please refer to traefik folder

^ back to top ^

Middlewares

This is a basic authentification using htpasswd:

  • create a file credentials, in this this example the password is admin:
admin:$2y$10$ocoMnzD3D0V86vPg5zWeA./oDTTxqf.zpHfzEE4R4VwIl1CAJaSWa
  • add this fil to you docker-compose.yml
reverse-proxy:
     
     volumes:
       # authentification
       - ./credentials:/credentials:ro
     
  • add the followings labels to any of your container:
      - traefik.http.routers.<container_name>.middlewares=auth-middleware
      - traefik.http.middlewares.auth-middleware.basicauth.usersfile=/users_credentials

Don't forget to replace `<container_name> by the name of your container.

Ans that's it

^ back to top ^

docker-101's People

Contributors

krystek17 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.