Tag: docker-compose

Building dnsmasq docker-compose file with DHCP enabled

Building dnsmasq docker-compose file with DHCP enabled

Creating Dockerfile

Create Dockerfile as below, the VOLUME /data is pointing to configuration folder

FROM ubuntu:latest

VOLUME /data

RUN apt update
RUN apt install dnsmasq -y
RUN apt install iproute2 -y

CMD dnsmasq -q -d --conf-file=/data/dnsmasq.conf --dhcp-broadcast

Creating docker-compose.yml file

Must add cap_add parameter.

version: '2'

services:
  dnsmasq:
    container_name: dnsmasq
    image: dnsmasq
    build:
      context: .
      dockerfile: Dockerfile.dnsmasq
    restart: unless-stopped
    volumes:
      - /app/dnsmasq/data:/data
    networks:
      - my_macvlan_250
    cap_add:
      - NET_ADMIN

networks:
  my_macvlan_250:
    external: true

This is the same as below command

docker run --cap-add=NET_ADMIN --name dnsmasq -d -it --restart unless-stopped -v /app/dnsmasq/data:/data --network my_macvlan_250 dnsmasq

References

Enable HTTPS for NextCloud Docker using `docker-compose`

Enable HTTPS for NextCloud Docker using docker-compose

By default, NextCloud Docker doesn't enable HTTPS.

Steps

Create

  • Create folders
    • /app/nextcloud/data/db: for MySQL database
    • /app/nextcloud/data/db_conf: for MySQL database configuration (don't see anything in it)
    • /app/nextcloud/data/cert: for nextcloud certificates
    • /app/nextcloud/data/html: for nextcloud data and packages
  • Create docker-compose.yml
  • Create Dockerfile.nextcloud
  • Run docker-compose build
  • Run docker-compose up -d

Destroy

  • Run docker-compose down

Docker Compose

docker-compose.yml:

version: '3'

services:
  db:
    image: mariadb:latest
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - /app/nextcloud/data/db:/var/lib/mysql
      - /app/nextcloud/data/db_conf:/etc/mysql/conf.d
    environment:
      - MYSQL_ROOT_PASSWORD=<mysql_root_password>
      - MYSQL_PASSWORD=<mysql_user_password>
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  app:
    build:
      context: .
      dockerfile: Dockerfile.nextcloud
    restart: always
    ports:
      - 80:80
      - 443:443
    links:
      - db
    volumes:
      - /app/nextcloud/data/html:/var/www/html
      - /app/nextcloud/data/cert/fullchain.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
      - /app/nextcloud/data/cert/privkey.pem:/etc/ssl/private/ssl-cert-snakeoil.key
    environment:
      - MYSQL_PASSWORD=<mysql_user_password>
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=db

Dockerfile.nextcloud

  • Define base docker image as nextcloud:latest
  • Enable ssl module
  • Enable default-ssl site
FROM nextcloud:latest

RUN a2enmod ssl
RUN a2ensite default-ssl

References

Docker Compose – Flask/Redis sample

Docker Compose - Flask/Redis sample

Files

app.py

from flask import Flask, request, jsonify
from redis import Redis

app = Flask(__name__)
redis = Redis(host="redis", db=0, socket_timeout=5, charset="utf-8", decode_responses=True)

@app.route('/', methods=['POST', 'GET'])
def index():

    if request.method == 'POST':
        name = request.json['name']
        redis.rpush('students', {'name': name})
        return jsonify({'name': name})

    if request.method == 'GET':
        return jsonify(redis.lrange('students', 0, -1))

Dockerfile

FROM python:3.7.0-alpine3.8

WORKDIR /usr/src/app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV FLASK_APP=app.py

CMD flask run --host=0.0.0.0

Build

docker-compose build

Network

docker network ls

This will show a network named as flash-redis_default created, which used by both flash and redis containers. The containers can use service name to communicate to each other.

Use parameters and arguments

Create a file called .env

PYTHON_VERSION=3.7.0-alpine3.8
REDIS_VERSION=4.0.11-alpine
DOCKER_USER=takacsmark

In docker-compose.yml file, replace environment session with env_file: .env.txt session, then use environment variable to define argument

version: "3"

services:
  app:
    build:
      context: .
      args:
        - IMAGE_VERSION=${PYTHON_VERSION}
    image: ${DOCKER_USER}/flask-redis:1.0
    env_file: .env.txt
    ports:
      - 80:5000
    networks:
      - mynet
  redis:
    image: redis:${REDIS_VERSION}
    networks:
      - mynet
    volumes:
      - mydata:/data

networks:
  mynet:
volumes:
  mydata:

In Dockerfile use argument from docker-compose.yml file

ARG IMAGE_VERSION

FROM python:$IMAGE_VERSION

WORKDIR /usr/src/app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV FLASK_APP=app.py

CMD flask run --host=0.0.0.0

docker and docker-compose commands

docker-compose ps
docker-compose logs
docker-compose logs -f app
docker-compose stop
docker-compose start
docker-compose restart
docker-compose kill
docker-compose top

exec

docker-compose exec redis redis-cli lrange students 0 -1
docker-compose exec app /bin/bash

run

Start a new container, but port mapping will not be applied for new container by default.

docker-compose run ls -al

Desired state

Docker compose is defining the desired state, which will update the existing containers after configuration changed if possible.

For example, update port in doctor-compose.yml file, once run docker-compose up -d again, only app server will be recreated.

Note: Don't need to destroy existing containers first before run up again.

Scale

docker-compose up --scale app=3

Note: If ports session defined, there will be conflicting of port map.

Network

In docker-compose.yml file

services:
  app:
      networks:
      - mynet

networks:
  mynet:

Then a network called <project_name>_mynet will be created.

The old network can be pruned

docker network prune

External network

Network can be defined outside of docker-compose.yml file, which indicated as external network

networks:
  outside:
    external:
      name: actual-name-of-network

volumes

docker volumes ls

In docker-compose.yml file

services:
  redis:
    volumes:
      - mydata:/data

volumes:
  mydata:

Then a volume called <project_name>_mydata will be created.

Configuration Override

Single override file

The options in docker-compose.override.yml will overwrite or extend options in docker-compose.yml.

Note: Array options will be extended.

Multiple override files

docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.dev.yml up -d

Migrate to cloud

Push images to docker hub

docker-compose push

Pull and run in play with docker (PWD)

docker-compose pull
docker-compose up -d

Sample data

Add sample data into redis

curl --header "Content-Type: application/json" \
--request POST \
--data '{"name":"Bruno"}' \
http://ipxxxxxxxxx.direct.labs.play-with-docker.com/

To access the sample data

curl http://ipxxxxxxxxx.direct.labs.play-with-docker.com/

Compose file reference

https://docs.docker.com/compose/compose-file/

Note: some options are only working in swarm mode or compose mode. For example, deploy only works in swarm mode, build only works in compose mode.

References

Docker compose tutorial for beginners by example [all you need to know] (Video)
Docker compose tutorial for beginners by example [all you need to know]

Docker Compose – Basic

Docker Compose - Basic

Commands

  • Start all services
docker-compose up
  • Stop all services
docker-compose down
  • Command to install Docker Compose
pip install -U docker-compose
  • Command to check the version of Docker Compose
docker-compose -v
  • Command to run docker compose file
docker-compose up -d
  • Command to list done all the process
docker-compose up -d --scale
  • Command to use YAML file to configure application services
docker-compose.yaml
  • Check logs
docker-compose logs

Docker Compose – wordpress

Docker Compose - wordpress

Simple steps to start using docker compose to create wordpress dockers.

Installation

Install docker-compose package

Run following command on ubuntu and armbian servers.

apt install docker-compose

Create dockers

Create folder as project name wp

The project name will be used as a part of docker container name.

mkdir -p /app/wp

Create docker compose file

Using vi to create file docker-compose.yml in directory /app/wp

version: "3.3"

services:
  db:
    image: mariadb:latest
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "80:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

Run docker compose command

docker-compose up -d

Destroy dockers

Run docker compose command

docker-compose down

Destroy dockers and their volumes

docker-compose down --volumes