2017年10月

Docker 搭建 Nginx 服务器

使用 Docker 部署应用,一般遵循“数据在宿主机,程序在容器”的原则。通过数据卷把有用的数据保存在本机(宿主机),避免因容器挂掉或者误删导致数据丢失。

下面我们通过 Docker 来搭建 Nginx 服务器。

首先在宿主机创建一个目录(如 /root/container/nginx),集中保存 Nginx 的配置文件、日志、应用程序代码:

mkdir -p /root/container/nginx/log
mkdir /root/container/nginx/conf
mkdir /root/container/nginx/www

下一步,复制初始的 Nginx 配置文件。原理是创建一个临时的 Nginx 容器,从中复制配置文件到宿主机。最后删除临时

docker run --name tmp-nginx-container -d nginx
docker cp tmp-nginx-container:/etc/nginx/nginx.conf /root/container/nginx/conf/nginx.conf
docker cp tmp-nginx-container:/etc/nginx/conf.d /root/container/nginx/conf/conf.d
docker cp tmp-nginx-container:/usr/share/nginx/html /root/container/nginx/www
docker rm -f tmp-nginx-container

最后运行镜像:

docker run --name nginx \
    -v /root/container/nginx/conf/conf.d:/etc/nginx/conf.d:ro \
    -v /root/container/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
    -v /root/container/nginx/www:/usr/share/nginx/:ro \
    -v /root/container/nginx/log:/var/log/nginx \
    -p 80:80 \
    -d nginx

上面的容器,映射了宿主机的 80 端口。可以在浏览器中打开如下载址,查看是否部署成功:

http://<;host_ip>:80

看到熟悉的欢迎语,就表示搭建成功:

Welcome to nginx!

Docker 部署一个 Node.js Web 项目[译]

(本文翻译自 Node.js 官方网站的帮助文档)

这个例子的目的是,向你展示如何将一个 Node.js 项目部署到 Docker 容器。这篇指导只适用于开发环境,不适合生产环境。这篇指导也假定你已经成功安装了 Docker,而且对 Node.js 项目的结构有一个基本的认识。

在这篇指导的第一部分,我们将用 Node.js 创建一个简单的 Web 应用,然后我们为那个应用构建一个 Docker 镜像,最后我们来运行这个镜像,作为一个容器。

在软件开发中,Docker 允许你打包一个应用,包含它的全部依赖程序,产生一个标准化的单元,叫作容器。容器是一个最小化的、基础的 Linux 操作系统。镜像是加载到容器的软件。

创建 Node.js 应用

首先,创建一个存放所有文件的目录。在这个目录中创建名为 package.json 的文件,它描述了这个应用以及它的依赖程序:

{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "First Last <first.last@example.com>",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.13.3"
  }
}

然后创建名为 server.js 的文件,它用 Express.js 框架定义了一个 Web 应用:

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello world\n');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

在下面的步骤,我们将看到你如何用官方的 Docker 镜像,在容器中运行这个应用。首先,你要用你的应用构建一个 Docker 镜像。

创建 Dockerfile

创建一个空文件叫 Dockerfile

touch Dockerfile

用你喜欢的文本编辑器打开 Dockerfile 这个文件。

第一件事,我们要做的是指定从哪个镜像构建。这里我们使用最新的 LTS(long term support) 版本,在 Docker hub 上可获取的 boron 版本的 node

FROM node:boron

下一步我们在镜像中创建一个目录,存放项目代码,这将是项目的工作目录。

# Create app directory
WORKDIR /usr/src/app

这个镜像中已经安装了 Node.js 和 NPM 软件,所以下一步我们要做的是使用 NPM 安装项目的依赖程序。请注意,如果你使用的是 NPM 5 或者更高版本,你还需要复制 package-lock.json,这个文件是在运行 npm install 时生成的:

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

注意,相比复制整个工作目录,我们只是复制了 package.json 文件。这允许我们利用 Docker 缓存层。bitJudo 对此有更好的解释

使用 COPY 指令,将项目源代码打包进 Docker 镜像:

# Bundle app source
COPY . .

你的应用绑定在 8080 端口,因此你要用 EXPOSE 指令将它暴露出来:

EXPOSE 8080

最后,指定运行应用的命令 CMD,它定义了运行时。这里我们使用 npm start 命令,它将运行 node server.js 来启动服务器。

CMD [ "npm", "start" ]

现在你的 Dockerfile 应该是下面这个样子:

FROM node:boron

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "start" ]

.dockerignore 文件

Dockerfile 文件所在的目录中创建一个 .dockerignore 文件,内容如下:

node_modules
npm-debug.log

这可以避免本地的模块和 debug 日志文件被复制到 Docker 镜像中,也可以避免镜像内部安装的模块。

创建镜像

进入 Dockerfile 所在的目录,执行下面的命令来构建 Docker 镜像。-t 参数给你的镜像打一个标签(相当于镜像名称),这样可以更容易通过 docker images 命令找到它:

$ docker build -t <your username>/node-web-app .

现在用 Docker 命令列出你的镜像如下:

$ docker images

# Example
REPOSITORY                      TAG        ID              CREATED
node                            boron      539c0211cd76    3 weeks ago
<your username>/node-web-app    latest     d64d3505b0d2    1 minute ago

运行镜像

用 -d 参数使镜像运行在 detach 模式,也就是让容器在后台运行。-p 参数映射一个公共的端口到容器内部的端口。运行刚才创建的镜像:

$ docker run -p 49160:8080 -d <your username>/node-web-app

打印应用程序的输出:

# Get container ID
$ docker ps

# Print app output
$ docker logs <container id>

# Example
Running on http://localhost:8080

如果想进入容器,可以使用 exec 命令:

# Enter the container
$ docker exec -it <container id> /bin/bash

测试

要测试这个应用,需要知道 Docker 映射的端口:

$ docker ps

# Example
ID            IMAGE                                COMMAND    ...   PORTS
ecce33b30ebf  <your username>/node-web-app:latest  npm start  ...   49160->8080

在上面的例子中,Docker 将容器内的端口 8080 映射到你的机器的 49160 端口。

现在你可以用 curl 命令访问你的程序(如有需要通过这个命令安装:sudo apt-get install curl):

$ curl -i localhost:49160

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
Date: Sun, 02 Jun 2013 03:53:22 GMT
Connection: keep-alive

Hello world

我们希望这个教程,帮助你在 Docker 中运行一个简单的 Node.js 应用程序。

原文:Dockerizing a Node.js web app

SVN 使用入门

svn 是一个文件版本控制管理系统,可用于团队代码管理、文档共享。

1.svn 地址与账号

一般会提供两种协议的使用方式:svn, http。比如 svn 管理员提供的使用地址是

http://192.168.1.1/svn/repo1/
svn://192.168.1.1/repo1

同时管理员会为你创建账号和密码。两种协议使用两套账号,如果管理员设置为相同,则使用时就像一套账号。一般 http 协议使用公共的账号即可,只可浏览文件。svn 协议则使用管理员分配的账号。

http 方式,只要在浏览器上打开上面的 http 地址,输入账号、密码,即可访问。

2. 客户端使用

2.1 Windows

使用 TortoiseSVN,这是目前使用最广泛的 svn 客户端。到官网下载、安装。

检出仓库

右键点击 SVN 检出(SVN Checkout...),打开如下界面,输入 svn 协议地址

svn_checkout.png

点击确定,会弹出账号密码输入界面,正确输入后即可。顺利的话,会在当前目录创建 repo1 文件夹,并且下载这个仓库中全部的文件。

提交文件

如果修改了文件,或者增加、删除了文件,可以将它提交到服务器,这样别人就能看到你的改动。

右键点击 SVN 提交(SVN Commit...),打开如下界面,勾选要提交的改动,填写修改备注(非必填),提交即可。

svn_commit.png

注意:如果无法提交文件(例如报错Can't open file '/home/svn/repo1/db/txn-current-lock': Permission denied),请确保上一步检出的地址,是 svn 协议地址,并且(与管理员确认)账号拥有写权限。http 协议的地址,只能查看。

撤销本地修改

如果修改了文件,还未提交,想撤销。

右键 -> TortoiseSVN -> 回滚(Revert...),可以回退到上一个版本。

Docker 搭建 Gitlab 服务器

1.下载镜像与运行容器

docker run --detach \
    --hostname code.example.com \
    --publish 20443:443 --publish 20080:80 --publish 20022:22 \
    --name gitlab \
    --restart always \
    --volume /root/container/gitlab/config:/etc/gitlab \
    --volume /root/container/gitlab/logs:/var/log/gitlab \
    --volume /root/container/gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce:latest

一般的情况下,宿主机 80 端口已经被占用,因此上面的端口映射使用其它端口。如果想使用域名,且不使用端口号,可以使用 Nginx 服务器作转发。

server {
    listen       80;
    server_name  code.example.com;

    location / {
        proxy_pass http://<host_ip>:20080;
    }
}

其中 host_ip 为宿主机 IP 地址。

2.配置

主要是修改 /root/container/gitlab/config/gitlab.rb,详细配置请参考另一篇文章《虚拟机搭建 Gitlab 服务器》配置邮件服务部分。

打开网址 http://code.example.com,显示 Gitlab 登录页。需要设置一个密码,这个密码就是管理员账号(root)的密码。

3.更新 Gitlab

停止并且删除容器,摘取最新的 docker 镜像。然后重新执行上面运行容器的命令。确保数据卷的配置,宿主机的路径不能变。

Docker 搭建 svn 服务器

svn 是一种集中式版本管理系统。最新文件存储在服务器上,用户需要先从服务器下载(检出)最新文件,修改后再提交到服务器。版本信息也是放在服务器上,如果连接不上服务器,则无法提交、还原、对比等操作。

优点是符合一般的思维逻辑,适合做团队内部文档共享、管理系统。

1.下载镜像与运行容器

docker run --name svn \
    --detach \
    --volume /root/container/svn:/var/opt/svn \
    --publish 3690:3690 \
    garethflowers/svn-server

以上命令运行的镜像是 garethflowers/svn-server,如果本地没有则会下载。

2.创建新的仓库

docker exec -it svn svnadmin create repo1

创建一个名为 repo1 的仓库。查看其对应的文件目录,包含如下文件:

ls /root/container/svn/repo1
conf  db  format  hooks  locks  README.txt

3.修改配置文件

仓库路径下 conf 为配置文件目录,有以下文件:

ls ./repo1/conf
authz  hooks-env.tmpl  passwd  svnserve.conf

修改 svnserve.conf

[general]
anon-access = none             # 匿名用户不可读写,也可设置为只读 read
auth-access = write            # 授权用户可写
password-db = passwd           # 密码文件路径,相对于当前目录
authz-db = authz               # 访问控制文件
realm = /var/opt/svn/repo1     # 认证命名空间,会在认证提示界面显示,并作为凭证缓存的关键字,可以写仓库名称

配置账号与密码,修改 passwd,格式为“账号 = 密码”

[users]
# harry = harryssecret
# sally = sallyssecret
eric = 123456

配置权限,修改 authz


[groups]
owner = eric, user1

[/]             # / 表示所有仓库
eric = rw       # 用户 eric 在所有仓库拥有读写权限

[repo1:/]           # 表示以下用户在仓库 repo1 的所有目录有相应权限
user1 = rw
@owner = rw         # 表示 owner 组下的用户拥有读写权限

说明,r 表示读,w 表示写。没有设置的用户默认为无权限。
注意:更改svnserve.conf,authz和passwd文件时不需要重启。


附加内容

上面的 svn 服务器不支持 http 协议访问,如果要支持,可以在上面的容器中安装 Apache 服务器及相应的模块(mod_dav_svn),配置好即可。并将其提交、生成一个新的镜像保存下来。

当然也可以使用 Docker Hub 上已经支持 http 协议访问的镜像。

准备工作:

# 生成一个空的密码文件,用于 Apache 的 HTTP 认证
mkdir -p /root/container/svn/apache
touch /root/container/svn/apache/passwd

运行容器:

docker run -d \
    --name svn-server \
    -p 21080:80 \
    -p 3690:3960 \
    --volume /root/container/svn/repo:/home/svn \
    --volume /root/container/svn/apache/passwd:/etc/subversion/passwd \
    elleflorio/svn-server

创建 http 访问账号

docker exec -t svn-server htpasswd -b /etc/subversion/passwd <username> <password>

此账号和密码被写入容器中的 HTTP 认证文件(/etc/subversion/passwd),且密码是加密的。实践经验表明,既然用 http 协议访问只能查看,那么创建一个公共的账号,供大家使用即可。也可创建与 svn 认证文件中一样的账号和密码。

创建新的仓库

docker exec -it svn-server svnadmin create repo1

svn 客户端的账号权限则在 repo1/conf 的配置文件中配置。见本文前一部分配置说明。


备份数据

svn 存储数据有2种方式:BDB(一种事务安全型表类型)和FSFS(一种不需要数据库的存储系统)。
仓库文件(数据)存储路径为 ./repo1/db/revs,注意保护好。一般直接备份整个仓库 ./repo1/。