一種 Dockerize 應用的簡單方式

一種 Dockerize 應用的簡單方式

標籤(空格分隔): Docker dockerizehtml


做者是 jasonwilder。原文地址是 A Simple Way to Dockerize Applicationslinux

Dockerizing 一個應用是轉化一個應用運行在 Docker 容器中的過程。雖然 dockering 大部分應用是簡單的,可是這裏每次都有一些問題圍繞着工做。每次工做的時候有幾個問題都須要待解決。nginx

在 dockerization 時兩個常見的問題是:git

  1. 當它依賴於配置文件時,使得應用使用環境變量
  2. 發送應用日誌到 STDOUT/STDERR,當它默認記錄在 Docker 的文件系統

這篇文章介紹一個新工具:dockerize ,它簡化了這兩個常見的問題。github

問題

配置

許多應用使用配置文件來控制它們怎麼工做,不一樣的運行環境有不一樣的值。好比,對於一個開發環境的數據庫鏈接細節將與生產環境的不一樣。相似的,API keys 和其餘的敏感細節在不一樣環境將不一樣。docker

使用 docker 容器有幾個方法能夠處理這些環境變量的問題:數據庫

  1. 在鏡像中嵌入全部的環境變量細節和使用一個控制環境變量變量來指出在運行時使用哪一個文件。(好比:APP_CONFIG=/etc/dev.config)
  2. 在運行時,使用捲來掛載綁定配置文件的數據
  3. 使用封裝腳本,使用工具像 sed 那些環境變量來修改配置數據

嵌入全部的環境變量細節是不理想的,由於環境變量的改變應該不須要從新構建一個鏡像。它也缺乏安全,由於敏感數據 API keys, login 證書等等,做爲環境變量被存儲在鏡像中。私發一個開發環境可能會泄露生產環境細節。有些類型的細節在任何鏡像中都應該避免的。
使用 volumes 保持這些細節在鏡像外面,但會使得部署更復雜,由於你不只部署鏡像。你必須使配置文件的變動和鏡像協調。ubuntu

注入環境變量到普通文件中也不是重要的。你可能有時會製做一個 sed 命令或寫一些普通的腳本給它,但這是重複性的工做。這確實產生了一個鏡像,但在 Docker 生態系統中工做的很好。安全

Logging

Docker 容器日誌記錄到 STDOUT 和 STDERR 更容易故障排解,監控和融入一個中央日誌系統。日誌能夠經過 docker logs 命令和 Docker 日誌 API 調用來直接訪問。這也有許多工具能夠自動拉取 docker 日誌和運送它們若是日誌記錄進 STDOUT 和 STDERR。服務器

不幸地是,默認,許多應用日誌記錄一個或多個文件到文件系統上。雖然這一般能夠圍繞工做,計算出每一個應用的日誌配置的細微差異是乏味的。

使用 Dockerize

dockerize 是一個小型的 Golang 應用,能夠經過如下簡化 dockerization 過程:

  1. 在啓動時使用模板生成配置文件和容器環境變量
  2. tail 任意的日誌文件到 STDOUT 和 STDERR
  3. 啓動一個進程,運行在容器裏面

一個示例

爲了證實它怎樣工做,咱們將詳細講述使用 dockerize 來 dockerizing 一個通常的 nginx 的過程。

FROM ubuntu:14.04

# Install Nginx.
RUN echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" > /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN echo "deb-src http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
RUN apt-get update
RUN apt-get install -y nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

EXPOSE 80

CMD nginx

下一步,咱們將安裝 dockerize 和經過它運行 nginx

FROM ubuntu:14.04

# Install Nginx.
RUN echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" > /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN echo "deb-src http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
RUN apt-get update
RUN apt-get install -y wget nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

RUN wget https://github.com/jwilder/dockerize/releases/download/v0.0.1/dockerize-linux-amd64-v0.0.1.tar.gz
RUN tar -C /usr/local/bin -xvzf dockerize-linux-amd64-v0.0.1.tar.gz

ADD dockerize /usr/local/bin/dockerize

EXPOSE 80

CMD dockerize nginx

默認 Nginx 在 /var/log/nginx 目錄下記錄兩個不一樣的文件。若是你交互式的運行這個容器,這將有 nginx 的 access and error 日誌流到控制檯,或者是你運行 docker logs nginx,所以你能夠看到發生了什麼。

咱們能夠經過傳遞 -stdout <file>-stderr <file> 命令行選項來解決它。若是你有幾個文件須要 tail ,這裏能夠傳遞屢次。

CMD dockerize -stdout /var/log/nginx/access.log -stderr /var/log/nginx/error.log nginx

如今當你運行容器,nginx 日誌經過 docker logs nginx 是可用的。

爲了證實模板,咱們可使用環境變量配置讓這個變成一個更通用的代理服務器。咱們將定義環境變量 PROXY_URL 做爲一個站點的代理 URL。

PROXY_URL="http://jasonwilder.com"

當這個容器使用這個環境變量啓動,dockerize 將使用它來生成一個 nginx 的location 路徑。

這是模板:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;

    location / {
      access_log off;
      proxy_pass {{ .Env.PROXY_URL }};
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

這時咱們最後的 Dockerfile 將看起來這樣:

FROM ubuntu:14.04

# Install Nginx.
RUN echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" > /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN echo "deb-src http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list.d/nginx-stable-trusty.list
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
RUN apt-get update
RUN apt-get install -y wget nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

RUN wget https://github.com/jwilder/dockerize/releases/download/v0.0.1/dockerize-linux-amd64-v0.0.1.tar.gz
RUN tar -C /usr/local/bin -xvzf dockerize-linux-amd64-v0.0.1.tar.gz

ADD default.tmpl /etc/nginx/sites-available/default.tmpl

EXPOSE 80

CMD dockerize -template /etc/nginx/sites-available/default.tmpl:/etc/nginx/sites-available/default -stdout /var/log/nginx/access.log -stderr /var/log/nginx/error.log nginx

-template <src>:<dest> 選項指明 template 在 /etc/nginx/sites-available/default.tmpl 應該被生成並寫入 /etc/nginx/sites-available/default。多個模板也能夠被指定。

使用下面命令運行容器:

$ docker run -p 80:80 -e PROXY_URL="http://jasonwilder.com" --name nginx -d nginx

而後你能夠經過 http://localhost 訪問,它將代理到這個站點。

這是一個簡化的例子,可是使用嵌入的 split 函數和 range 聲明使它能夠很容易的被擴展來處理多個代理值和其餘選項。這裏有一些其餘的可用模板函數示例。

總結

雖然這個例子有點簡單,許多應用須要一些 shims 來使得在 Docker 中運行的更好。dockerize 是一個通用的工具來幫助你處理這個過程。

你能夠在 jwilder/dockerize 找到代碼。

相關文章
相關標籤/搜索