Skip to content

Instantly share code, notes, and snippets.

@kkweon
Last active August 24, 2021 16:43
Show Gist options
  • Save kkweon/2359da953f9b127b19c4146060797631 to your computer and use it in GitHub Desktop.
Save kkweon/2359da953f9b127b19c4146060797631 to your computer and use it in GitHub Desktop.

๋‚˜๋งŒ์˜ Docker Reference

Docker ํƒ€๊ฒŸ์œ ์ €

๋‹ค์Œ ์ค‘ ํ•˜๋‚˜ ์ด์ƒ ๊ฒฝํ—˜ํ•œ ์‚ฌ๋žŒ

๋นŒ๋“œ ๋ฌธ์ œ

๋‹ค๋ฅธ ์ปดํ“จํ„ฐ์—์„œ ๋นŒ๋“œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๊ฒฝ์šฐ

๋นŒ๋“œํˆด์ด ๋ฐœ์ „ํ•˜๋ฉด์„œ ๋งŽ์ด ๋‚˜์•„์กŒ์ง€๋งŒ ๊ทธ๋ž˜๋„ ๋‹ค๋ฅธ OS๋ฌธ์ œ๋ผ๋˜์ง€ ์—ฌ์ „ํžˆ ๊ฐ€๋”์”ฉ ์ ‘ํ•˜๋Š” ์ผ€์ด์Šค์ด๋‹ค.

ํ•ด๊ฒฐ๋ฒ• Dockerfile ์„ ์‚ฌ์šฉํ•œ๋‹ค

DB์‚ฌ์šฉ

DB๋ฅผ ์—ฐ๊ฒฐํ•ด์•ผ ๋˜๋Š”๋ฐ ๋‚ด ์ปดํ“จํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ

  • ์›น๊ฐœ๋ฐœ์„ ํ• ๋•Œ ํ”„๋กœ๋•์…˜๊ณผ ๋™์ผํ•œ ํ™˜๊ฒฝ์œผ๋กœ ์„ธํŒ…ํ•ด์•ผ ํ•˜์ง€๋งŒ ๊ท€์ฐฎ๋‹ค
  • ์ด๋ฏธ ๋‚ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์‚ฌ์šฉ์ค‘์ด๊ฑฐ๋‚˜ ํ˜น์€ ๊ท€์ฐฎ๋‹ค
  • ํฌ๋กค๋ง์„ ํ•˜๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ณ  ์‹ถ์€๋ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •ํ•˜๊ธฐ๊ฐ€ ๊ท€์ฐฎ๋‹ค

    ํ•ด๊ฒฐ๋ฒ• docker-compose ๋กœ ํ•ด๊ฒฐํ•œ๋‹ค.

๋ฐฐํฌ

๋ฐฐํฌ ๋„ˆ๋ฌด ๊ท€์ฐฎ๋‹ค..

๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ ํ™˜๊ฒฝ์„ค์ • ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€๋กœ ์„ค์ •์„ ์žก์•„ ์ฃผ๊ธฐ ๊ท€์ฐฎ์€ ์ƒํ™ฉ๋„ docker๋กœ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๊ฒฐ๋ฒ• docker stack deploy ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

Scalability

์„œ๋น„์Šค scalability๋„ ์‰ฝ๊ฒŒ ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค..

ํ•ด๊ฒฐ๋ฒ• docker service scale frontend=10 ํ•œ์ค„์ด๋ฉด ๋œ๋‹ค.

Docker์™€ ํ•จ๊ป˜ํ•˜๋Š” ๊ฐœ๋ฐœ workflow

Docker๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๊ฒŒ ๋œ๋‹ค

  1. Dockerfile ์ž‘์„ฑ
  2. docker-compose.yml ์ž‘์„ฑ
  3. ๊ฐœ๋ฐœ
    • docker-compose up
  4. ๋ฐฐํฌ
    • ์ด๋ฏธ์ง€ํ™” ๋ฐ registry
    • docker stack deploy

Docker ์—ฐ์Šต ํ™˜๊ฒฝ

http://labs.play-with-docker.com/

Dockerfile ์ž‘์„ฑ

  • Dockerfile ์€ docker image๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ์ด๋‹ค
  • Dockerfile ๋กœ image๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋ฉด container๋กœ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.
  • Virtualbox๋กœ ์น˜๋ฉด
    • image = isoํŒŒ์ผ
    • container = ์‹ค์ œ ์‹คํ–‰๋˜๋Š” ๊ฐ€์ƒํ™˜๊ฒฝ
    • ๋ฌผ๋ก  docker๋Š” virtualization์ด ์•„๋‹ˆ๋ผ ํ˜ธ์ŠคํŠธ์˜ ์ปค๋„์„ ์‚ฌ์šฉํ•ด์„œ ์‚ฌ์‹ค์ƒ Native Application์ด๋‹ค.

์˜ˆ์‹œ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ Flask App์ด ์žˆ๋‹ค.

from flask import Flask, render_template
import random

app = Flask(__name__)

# list of cat images
images = [
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-1376-1381846217-0.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3391-1381844336-26.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-29111-1381845968-0.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3409-1381844582-13.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr02/15/9/anigif_enhanced-buzz-19667-1381844937-10.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-18774-1381844645-6.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif",
    "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif"
]

@app.route('/')
def index():
    url = random.choice(images)
    return render_template('index.html', url=url)

if __name__ == "__main__":
    app.run(host="0.0.0.0")

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

.
โ”œโ”€โ”€ app.py
โ”œโ”€โ”€ requirements.txt
โ””โ”€โ”€ templates
    โ””โ”€โ”€ index.html

์œ„ ํ”„๋กœ์ ํŠธ๋กœ Dockerfile ์„ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

# FROM: ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€๋ฅผ ์ •ํ•ด์ค€๋‹ค.
FROM python:3-alpine

# requirements.txt ํŒŒ์ผ ๋ณต์‚ฌ
COPY requirements.txt /code/
RUN pip install --no-cache-dir -r /code/requirements.txt

# app.py์™€ index.html ๋ณต์‚ฌ
COPY app.py /code/
COPY templates/index.html /code/templates/

EXPOSE 5000

WORKDIR /code

CMD ["python", "app.py"]

์™ธ์šธ ํ•„์š”๋Š” ์—†๊ณ  ํ•„์š”ํ• ๋•Œ๋งˆ๋‹ค Dockerfile Reference ์—์„œ ์ฐพ์•„๋ณด๋ฉด ๋œ๋‹ค

๋ช‡๊ฐ€์ง€ ํฌ์ธํŠธ๋Š”

FROM
๋ฒ ์ด์Šค ์ด๋ฏธ์ง€๋ฅผ ์ •ํ•ด์ค€๋‹ค. ์ƒˆ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค official image ์œ„๋ฅผ ์ด์šฉํ•˜๋Š”๊ฒŒ ์ข‹๊ณ  alpine์€ ๋ฆฌ๋ˆ…์Šค ์ข…๋ฅ˜ ์ค‘ ํ•˜๋‚˜์ธ๋ฐ ์šฉ๋Ÿ‰์ด 5mb์— ๋ถˆ๊ณผํ•ด ๋Œ€๋ถ€๋ถ„ ๋ชจ๋“  ๊ณต์‹ ์ด๋ฏธ์ง€๋“ค์ด alpine์„ ์ง€์›ํ•œ๋‹ค.
EXPOSE
ํฌํŠธ 5000์„ ์—ด๊ฒ ๋‹ค๋Š” ์†Œ๋ฆฌ์ด์ง€๋งŒ ์‹ค์ œ๋กœ ์•„๋ฌด ์ผ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ํฌํŠธ 5000๋ฒˆ์—์„œ ์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋Œ์•„๊ฐ„๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋Š” ์šฉ๋„์ด๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํฌํŠธ ๋ช‡๋ฒˆ์„ ์—ฐ๊ฒฐํ•ด์ค˜์•ผ ๋˜๋Š”์ง€ ํ—ท๊ฐˆ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์‹ค์ œ๋กœ๋Š” ENV ํ˜น์€ ARG ๋กœ ์„ค์ •ํ•ด์ค€๋‹ค.

์ด์ œ ์ด๊ฑธ ์ด๋ฏธ์ง€๋กœ ๋นŒ๋“œํ•œ๋‹ค

docker build -t my_flask_app .
Sending build context to Docker daemon   7.68kB
Step 1/8 : FROM python:3-alpine
 ---> d26cf7d4701d
Step 2/8 : COPY requirements.txt /code/
 ---> Using cache
 ---> 459e0df94893
Step 3/8 : RUN pip install --no-cache-dir -r /code/requirements.txt
 ---> Using cache
 ---> 5a618308e9b8
Step 4/8 : COPY app.py /code/
 ---> Using cache
 ---> e35197a2ee91
Step 5/8 : COPY templates/index.html /code/templates/
 ---> Using cache
 ---> 734c689d69e3
Step 6/8 : EXPOSE 5000
 ---> Using cache
 ---> 0c4d7984da84
Step 7/8 : WORKDIR /code
 ---> Using cache
 ---> 89bfc8e45446
Step 8/8 : CMD python app.py
 ---> Using cache
 ---> 51fb98413e28
Successfully built 51fb98413e28
Successfully tagged my_flask_app:latest

๋นŒ๋“œ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ์„ ํ•œ๋‹ค

docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my_flask_app        latest              51fb98413e28        20 seconds ago      98.7MB

image๋ฅผ container๋กœ ์‹คํ–‰์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

docker container run --name flask --publish 8080:5000 -d my_flask_app
fee755b1f3b34bff0b8d8f676a696976cfe4b24b9555b7257428c56ab799424d

๊ตฌ) ์ปค๋งจ๋“œ์ธ docker run ์œผ๋กœ ํ•ด๋„ ๋˜์ง€๋งŒ ์‹ ๋ช…๋ น์–ด๋Š” docker <<context>> <<command>> ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ฆ‰ ์—ฌ๊ธฐ์„œ๋Š” docker container run ์ธ ๊ฒƒ์ด๋‹ค. ์ปค๋งจ๋“œ๋„ ๋งค๋ฒˆ --help ๋ฅผ ๋ณด๋ฉด ๋œ๋‹ค.

docker container --help
Usage:	docker container COMMAND

Manage containers

Options:
      --help   Print usage

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.

์–ด์จŒ๋“  docker container run ์ดํ›„ container id๊ฐ€ ๋ฐ˜ํ™˜๋˜์—ˆ์œผ๋ฉด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋œ ๊ฒƒ์ด๋‹ค. ํ™•์ธ์„ ํ•˜๋ฉด ๋™์ž‘์ค‘์ธ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

GET 127.0.0.1:8080
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 732
Server: Werkzeug/0.12.2 Python/3.6.3
Date: Sat, 07 Oct 2017 08:19:33 GMT

<html>
  <head>
    <style type="text/css">
      body {
        background: black;
        color: white;
      }
      div.container {
        max-width: 500px;
        margin: 100px auto;
        border: 20px solid white;
        padding: 10px;
        text-align: center;
      }
      h4 {
        text-transform: uppercase;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h4>Cat Gif of the day</h4>
      <img src="http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif" />
      <p><small>Courtesy: <a href="http://www.buzzfeed.com/copyranter/the-best-cat-gif-post-in-the-history-of-cat-gifs">Buzzfeed</a></small></p>
    </div>
  </body>
</html>

์•„๋ž˜์™€ ๊ฐ™์ด ์‹คํ–‰์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
fee755b1f3b3        my_flask_app        "python app.py"     27 minutes ago      Up 27 minutes       0.0.0.0:8080->5000/tcp   flask

๊ท€์ฐฎ์œผ๋‹ˆ force๋กœ ์ง€์šด๋‹ค

docker container rm -f flask

์—†์–ด์กŒ๋‹ค.

docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

docker-compose.yml ์ž‘์„ฑ

์‹ค์ œ๋กœ docker๋ฅผ ์‚ฌ์šฉํ• ๋•Œ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ์ „์— Dockerfile ๊ณผ docker-compose.yml ๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋†“๊ณ  ์‹œ์ž‘์„ ํ•œ๋‹ค.

์ด์ œ๋ถ€ํ„ฐ๋Š” ํ—ˆ์ ‘ํ•œ DevOps ๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์„ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

  • drupal 8.2 ๋ฒ„์ „์„ ์„ค์น˜ํ•œ๋‹ค
  • drupal bootstrap theme์„ ์„ค์น˜ํ•œ๋‹ค
  • port๋Š” 8080์„ ์ด์šฉํ•œ๋‹ค.
  • database๋Š” postgres 9.6 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•œ๋‹ค
  • postgres password๋Š” qwer1234qwer ๋กœ ํ•œ๋‹ค
  • ๋ฐ์ดํ„ฐ๋Š” container๊ฐ€ ๋‚ ์•„๊ฐ€๋„ ๋ณด์กดํ•˜๋„๋ก ํ•œ๋‹ค

์šฐ์„  ๊ฐ€์žฅ ๋จผ์ € ํ• ์ผ์€ Dockerfile ์„ ๋งŒ๋“œ๋Š” ์ผ์ด๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” ์—†์–ด๋„ ๋˜๊ธด ํ•˜์ง€๋งŒ ๊ทธ๋ƒฅ ํ•œ๋‹ค.

FROM drupal:8.2
RUN apt-get update                \
    && apt-get install -y git     \
    && rm -rf /var/lib/apt/lists*

WORKDIR /var/www/html/themes

RUN git clone --branch 8.x-3.x --single-branch --depth 1 https://git.drupal.org/project/bootstrap.git \
    && chown -R www-data:www-data bootstrap

WORKDIR /var/www/html

/var/www/html ์ด๋‚˜ ์ด๋Ÿฐ๊ฑด ์–ด๋–ป๊ฒŒ ์•Œ์ˆ˜ ์žˆ๋Š”๊ฐ€? Dockerhub/drupal ์—์„œ ์˜ฌ๋ ค๋†“์€ README ๋ฅผ ๋ณด๋ฉด ๋œ๋‹ค.

docker-compose.yml ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

version: "3"
services:

  drupal:
    build: .
    image: custom-drupal
    depends_on:
      - db
    ports:
      - 8080:80
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - drupal-themes:/var/www/html/themes

  db:
    image: postgres:9.6
    environment:
      POSTGRES_PASSWORD: qwer1234qwer
    volumes:
      - drupal-data:/var/lib/postgresql/data

volumes:
  drupal-data:
  drupal-modules:
  drupal-profiles:
  drupal-sites:
  drupal-themes:
  • yaml ํฌ๋งท์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • volumes์€ ์‹ค์ œ ํ˜ธ์ŠคํŠธ์— ๋ณผ๋ฅจ์„ ์‚ฌ์šฉํ•ด ์ฝ˜ํ…Œ์ด๋„ˆ๊ฐ€ ์—†์–ด์ง€๋”๋ผ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚จ์•„์žˆ๊ฒŒ ๋œ๋‹ค.
    • ์•„๋ฌด๊ฒƒ๋„ ์ž‘์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด docker volume ์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • environment ๋ฅผ ํ†ตํ•ด ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ด๋Ÿฐ secret๋“ค์€ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•˜๋Š”๊ฑด ์ข‹์ง€ ์•Š๋‹ค.
    • ์‹ค์ œ๋กœ๋Š” docker secret ์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ž์„ธํ•œ ํ‚ค์›Œ๋“œ๋Š” Docker Compose Reference ์—์„œ ํ™•์ธํ•œ๋‹ค.

์ด์ œ ์‹คํ–‰์€ docker-compose up ์„ ์‚ฌ์šฉํ•œ๋‹ค. ๋จผ์ € help๋ฅผ ์‚ดํŽด๋ณธ๋‹ค.

docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   Show more output
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

์ด์ œ ์‹คํ–‰์„ ํ•œ๋‹ค.

docker-compose up -d
docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4d448b78b4fd        custom-drupal       "docker-php-entryp..."   19 seconds ago      Up 18 seconds       0.0.0.0:8080->80/tcp   drupal_drupal_1
4f2cf2a1722f        postgres:9.6        "docker-entrypoint..."   19 seconds ago      Up 18 seconds       5432/tcp               drupal_db_1

์ด์ œ ๋กœ์ปฌํ˜ธ์ŠคํŠธ:8080์œผ๋กœ ๊ฐ€๋ณด๋ฉด

GET 127.0.0.1:8080
HTTP/1.1 302 Found
Date: Sat, 07 Oct 2017 09:04:22 GMT
Server: Apache/2.4.10 (Debian)
X-Powered-By: PHP/7.1.5
Cache-Control: no-cache
Location: /core/install.php
Content-Length: 312
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="1;url=/core/install.php" />

        <title>Redirecting to /core/install.php</title>
    </head>
    <body>
        Redirecting to <a href="/core/install.php">/core/install.php</a>.
    </body>
</html>

drupal ์„ค์น˜๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ค‘์š”ํ•œ ์ ์€ db๋ฅผ ์„ ํƒํ•˜๋Š” ์‹œ์ ์—

  • postgreSQL ์„ ํƒ
  • DATABASE HOST๋Š” docker-compose.yml ์—์„œ ์ง€์ •ํ•ด์ค€ ์ด๋ฆ„์ธ http://db ์ด๋‹ค
  • USERNAME์€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— postgres ๊ธฐ๋ณธ๊ฐ’์ธ postgres ์ด๋‹ค
  • PASSWORD๋Š” qwer1234qwer ์ด๋‹ค

์‹ค์ „์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ architecture๋ฅผ ๋ฐฐํฌํ•ด์•ผ ๋˜๋Š” ์ผ์ธ ๊ฒฝ์šฐ,

https://image.ibb.co/iPKQ0b/architecture.png

docker-compose.yml ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

version: "3"
services:
  vote:
    image: dockersamples/examplevotingapp_vote:before
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure
    ports:
      - 80:80
    networks:
      - frontend

  redis:
    image: redis:3.2
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - frontend

  worker:
    image: dockersamples/examplevotingapp_worker
    deploy:
      placement:
        constraints: [node.role == manager]
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
    networks:
      - frontend
      - backend

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
    networks:
      - backend

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - 5001:80
    networks:
      - backend
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    depends_on:
      - db

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - 8080:8080
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  frontend:
  backend:

volumes:
  db-data:

networks ์„ค์ •

networks:
  frontend:
  backend:

์ด ๋ถ€๋ถ„์€ docker network ๋กœ ๋„คํŠธ์›Œํฌ๊ฐ€ ์ €์ ˆ๋กœ ์ƒ์„ฑ ๋œํ›„ ๊ฐ๊ฐ์˜ ์ฝ˜ํ…Œ์ด๋„ˆ๊ฐ€ ์†ํ•˜๋Š” ์˜ค๋ฒ„๋ ˆ์ด์—์„œ๋งŒ ์„œ๋กœ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

docker network create --driver overlay frontend
docker network create --driver overlay backend

๋ฐฐํฌ

์‹ค์ œ ๋ฐฐํฌ๋ฅผ ํ•  ๋•Œ๋Š” docker swarm ์„ ์ด์šฉํ•ด ์—ฌ๋Ÿฌ๋Œ€์˜ ๋…ธ๋“œ๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค์Œ

docker stack deploy -c docker-compose.yml voteapp

์ด์ „ docker-compose.yml ์—์„œ deploy ์— ๋“ค์–ด๊ฐ„ ์˜ต์…˜๋“ค์ด docker stack deploy ๋ฅผ ํ• ๋•Œ ์ ์šฉ๋˜๋Š” ์˜ต์…˜๋“ค์ธ ๊ฒƒ์ด๋‹ค.

๊ฒฐ๋ก ์€

  • docker-compose ๋Š” development ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ช…๋ น์–ด
  • docker stack deploy ๋Š” ์‹ค์ œ ๋ฐฐํฌํ•  ๋•Œ ์‚ฌ์šฉ ๋˜๋Š” ๋ช…๋ น์–ด
  • docker stack deploy ๋ฅผ ํ•  ๊ฒฝ์šฐ Dockerfile๋กœ ๋นŒ๋“œ๋ฅผ ๋ชปํ•œ๋‹ค
    • ๋ฐฐํฌ ์ด์ „์— ๋‚ด ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด registry ๋กœ ๋ชจ๋“  ๋…ธ๋“œ์— ์ ‘์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

registry ์‚ฌ์šฉ๋ฒ•

registry๋Š” ๋กœ์ปฌ ์ „์šฉ dockerhub ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์Šค์›œ ํด๋Ÿฌ์Šคํ„ฐ์— ์ž๋™์œผ๋กœ ๊ณต์œ ๊ฐ€ ๋œ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค.

docker service create --name registry -p 5000:5000 registry
docker tag my_app 127.0.0.1:5000/my_app
docker push 127.0.0.1:5000/my_app

์ด์ œ ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚ด ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

docker service create --name my_app 127.0.0.1:5000/my_app

secret ์‚ฌ์šฉ๋ฒ•

docker secret create psql_user psql_user.txt

ํ˜น์€

echo "postgresuser" | docker secret create psql_user -

๋กœ ์ƒ์„ฑํ•œ๋‹ค. (๋์— - ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค)

์‹ค์ œ ์ปจํ…Œ์ด๋„ˆ์—์„œ๋Š” /run/secrets/psql_user ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ํŒŒ์ผ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜์–ด์žˆ๋‹ค.

services:
  psql:
    image: postgres
    environment:
      POSTGRES_USER_FILE: /run/secrets/psql_user
      POSTGRES_PASSWORD_FILE: /run/secrets/psql_pass
    secrets:
      - psql_user
      - psql_pass


secrets:
  psql_user:
    file: ./psql_user.txt

  psql_pass:
    file: ./psql_pass.txt

์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋ณด์•ˆ ์ด์Šˆ๋กœ ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๊ธฐ๋ณด๋‹ค external: true ์„ธํŒ…์„ ํ•œ ํ›„ docker secret create ์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

secrets:
  psql_user:
    external: true

  psql_pass:
    external: true

docker-compose.yml ๊ด€๋ฆฌ๋ฒ•

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌ๋ฅผ ํ•œ๋‹ค.

docker-compose.yml
์ด๋ฏธ์ง€๋งŒ ์„ค์ •๋˜์–ด์žˆ๋Š” ๋ฒ ์ด์Šค ํŒŒ์ผ
docker-compose.override.yml
๊ฐœ๋ฐœ์‹œ ์‚ฌ์šฉ๋˜๋Š” config
docker-compose.prod.yml
์‹ค์ œ ๋ฐฐํฌ์‹œ ์‚ฌ์šฉ๋˜๋Š” config
docker-compose.test.yml
CI์—์„œ ์‚ฌ์šฉ๋˜๋Š” config

example

docker-compose.yml

version: '3.1'

services:

  drupal:
    image: drupal:latest

  postgres:
    image: postgres:9.6

docker-compose.override.yml

version: '3.1'

services:

  drupal:
    build: .
    ports:
      - "8080:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - ./themes:/var/www/html/themes

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - drupal-data:/var/lib/postgresql/data

volumes:
  drupal-data:
  drupal-modules:
  drupal-profiles:
  drupal-sites:
  drupal-themes:

secrets:
  psql-pw:
    file: psql-fake-password.txt

docker-compose.prod.yml

version: '3.1'

services:

  drupal:
    ports:
      - "80:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - drupal-themes:/var/www/html/themes

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - drupal-data:/var/lib/postgresql/data

volumes:
  drupal-data:
  drupal-modules:
  drupal-profiles:
  drupal-sites:
  drupal-themes:

secrets:
  psql-pw:
    external: true

docker-compose.test.yml

version: '3.1'

services:

  drupal:
    image: drupal
    build: .
    ports:
      - "80:80"

  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - ./sample-data:/var/lib/postgresql/data
secrets:
  psql-pw:
    file: psql-fake-password.txt

Node.js good default

# if you're doing anything beyond your local machine, please pin this to a specific version at https://hub.docker.com/_/node/
FROM node:6

RUN mkdir -p /opt/app

# set our node environment, either development or production
# defaults to production, compose overrides this to development on build and run
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV

# default to port 80 for node, and 5858 or 9229 for debug
ARG PORT=80
ENV PORT $PORT
EXPOSE $PORT 5858 9229

# check every 30s to ensure this service returns HTTP 200
HEALTHCHECK CMD curl -fs http://localhost:$PORT/healthz || exit 1

# install dependencies first, in a different location for easier app bind mounting for local development
WORKDIR /opt
COPY package.json /opt
RUN npm install && npm cache clean --force
ENV PATH /opt/node_modules/.bin:$PATH

# copy in our source code last, as it changes the most
WORKDIR /opt/app
COPY . /opt/app

# if you want to use npm start instead, then use `docker run --init in production`
# so that signals are passed properly. Note the code in index.js is needed to catch Docker signals
# using node here is still more graceful stopping then npm with --init afaik
# I still can't come up with a good production way to run with npm and graceful shutdown
CMD [ "node", "index.js" ]

phoenix

FROM ubuntu:latest

# Elixir requires UTF-8
RUN apt-get update && apt-get upgrade -y && apt-get install locales && locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

# update and install software
RUN apt-get install -y curl wget git make sudo \
    # download and install Erlang apt repo package
    && wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb \
    && dpkg -i erlang-solutions_1.0_all.deb \
    && apt-get update \
    && rm erlang-solutions_1.0_all.deb \
    # For some reason, installing Elixir tries to remove this file
    # and if it doesn't exist, Elixir won't install. So, we create it.
    # Thanks Daniel Berkompas for this tip.
    # http://blog.danielberkompas.com
    && touch /etc/init.d/couchdb \
    # install latest elixir package
    && apt-get install -y elixir erlang-dev erlang-dialyzer erlang-parsetools \
    # clean up after ourselves
    && apt-get clean


# install the Phoenix Mix archive
RUN mix archive.install --force https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez
RUN mix local.hex --force \
    && mix local.rebar --force

# install Node.js (>= 8.0.0) and NPM in order to satisfy brunch.io dependencies
# See http://www.phoenixframework.org/docs/installation#section-node-js-5-0-0-
RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - && sudo apt-get install -y nodejs

WORKDIR /code
COPY . /code
RUN mix deps.get && npm install && npm cache clean --force

EXPOSE 80 4000 4001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment