13. docker 迁移 GitLab 项目
最后更新于:2022-04-02 01:41:15
# 13. docker 迁移 GitLab 项目
#### 1. 介绍
现在我需要把docker部署的gitlab应用迁移到另一台主机上。
**如果不知道如何用docker来搭建gitlab服务的,可以参照我以前的一篇文章[使用 compose 部署 GitLab 应用 (八)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-gitlab-ying-yong-ba)**
#### 2. 流程
首先gitlab是会每天做一次备份的,备份文件位于`/srv/docker/gitlab/gitlab/backups`。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/7b77c28a5354b3fd0ea9cab1e96f6a22_2028x212.png)
这里有好多个备份,选一个日期最新的。
再把它上传到服务器上。
如果觉得都不新,可以创建一个最新的,使用下面的命令:
```
$ docker run --name gitlab -it --rm \
sameersbn/gitlab:9.0.5 app:rake gitlab:backup:create
```
不管怎样,就是要找一个备份,然后上传到新的服务器上。
注意:**这个备份所使用gitlab的版本和新的服务器上使用的gitlab的版本要一致,不然不能成功迁移的**
新的服务器的备份的文件存放的位置跟之前的一样,也是:`/srv/docker/gitlab/gitlab/backups`。
执行下面的命令可以恢复备份:
```
$ docker-compose run --rm gitlab app:rake gitlab:backup:restore
```
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/de04916642329082c233d735a6476fa8_1672x1192.png)
之后可能会报错:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/79c2c04093182de5d01830c6c3de3fc1_1726x1056.png)
没关系,你再把`docker-compose up`运行一下,再开一个终端去运行之前的恢复命令。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/6447465ff3229408db4bd1b599934b29_1006x1160.png)
数据库和仓库都会帮我恢复
所有数据都回来了,good job!
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d26c09a920d3fca45b0ada5cf814a637_2872x1242.png)
完结。
';
12. 让 php-fpm 跑的 owncloud 应用 docker 化
最后更新于:2022-04-02 01:41:13
# 12. 让 php-fpm 跑的 owncloud 应用 docker 化
#### 1. 介绍
之前我们介绍过owncloud的部署([部署 owncloud 与 phpMyAdmin (十一)](https://www.rails365.net/articles/bu-shu-owncloud-yu-phpmyadmin-shi-yi)),不管是owncloud还是phpMyAdmin都是php语言写的应用,owncloud这个容器默认是跑在apache下,我不太喜欢,想改成nginx+php-fpm来跑。
#### 2. 一个简单的实例
我们先来尝试一下用nginx结合php-fpm来跑php应用。
首先创建一个docker-compose.yml文件,内容如下:
```
version: '2'
services:
web:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
php:
image: php:fpm
volumes:
- ./code:/code
```
数据卷`./code`这个目录是放php代码的,还有一个文件`site.conf`放的是nginx的配置。
它的内容如下:
```
server {
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
```
nginx中使用fastcgi这个模块去连接php-fpm。这些是nginx中fastcgi的基本配置啦。
然后我们试着写些php的代码,让它跑起来:
在当前目录下的code目录下新建`index.php`文件,内容如下:
```
```
然后一行`docker-compose up`命令就可以跑起来,使用8080端口查看效果。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/b27a569ebb2d18e48ba23c4295963f98_1962x1268.png)
#### 3. 从apache迁移到php-fpm
现在尝试把owncloud用php-fpm来跑。
之前我们的docker-compose.yml是这么写的:
```
version: '2'
services:
owncloud:
restart: always
image: owncloud
ports:
- 18080:80
volumes:
- /home/hfpp2012/owncloud/html:/var/www/html:Z
depends_on:
- db
dns:
- 10.202.72.118
- 10.202.72.116
- 8.8.8.8
db:
restart: always
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
- MYSQL_DATABASE=owncloud_pro
volumes:
- /home/hfpp2012/owncloud/datadir:/var/lib/mysql
```
需要改造一下,把`owncloud`中的`image`和`ports`部分变一下:
```
image: owncloud:9.1.4-fpm
ports:
- 9000:9000
```
只是给owncloud换个版本,而且php-fpm默认是使用9000端口的。
使用`docker-compose up`或`docker-compose restart`重新把owncloud这个应用跑起来。
#### 4. nginx配置
接下来,我们把nginx的配置加上。
我们不用上面的那个很普通的关于fastcgi的配置,而owncloud的官方提供了一套比较标准的。
官方提供的那套nginx配置的网址是[https://doc.owncloud.org/server/9.0/admin\_manual/installation/nginx\_examples.html](https://doc.owncloud.org/server/9.0/admin_manual/installation/nginx_examples.html)
```
upstream php-handler {
server 127.0.0.1:9000;
#server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name file.rails365.net;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name file.rails365.net;
ssl_certificate /home/hfpp2012/owncloud/ssl/file.rails365.net.key.pem;
ssl_certificate_key /home/hfpp2012/owncloud/ssl/file.rails365.net.key;
# ssl_dhparam
ssl_dhparam /home/hfpp2012/owncloud/ssl/dhparam.pem;
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this topic first.
#add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Path to the root of your installation
root /home/hfpp2012/owncloud/html;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/acme-challenge { }
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Disable gzip to avoid the removal of the ETag header
gzip off;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
return 404;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
return 404;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off; #Available since nginx 1.7.11
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~* \.(?:css|js)$ {
try_files $uri /index.php$uri$is_args$args;
add_header Cache-Control "public, max-age=7200";
# Add headers to serve security related headers (It is intended to have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into this topic first.
#add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Optional: Don't log access to assets
access_log off;
}
location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
# Optional: Don't log access to other assets
access_log off;
}
}
```
在官方提供的配置的基础上,我做出了一些改变,除了证书和域名部分是一定要跟你的实际情况一致之外,还有如下改变:
- `root`这一行变成`root /home/hfpp2012/owncloud/html;`
- `fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;`变成了`fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;`
最后一个改变是为了解决一个nginx的报错问题而变的。我参考这篇文章进行了解决:
除此之外,有一个地方值得注意,如果不使用https的话,除了改变433端口为80端口一些必要的改变,还需要把下面一行注释掉:
```
fastcgi_param HTTPS on;
```
完结。
';
11. 部署 owncloud 与 phpMyAdmin
最后更新于:2022-04-02 01:41:11
# 11. 部署 owncloud 与 phpMyAdmin
#### 1. 介绍
上一篇:[docker部署深入理解(十)](https://www.rails365.net/articles/docker-bu-shu-shen-ru-li-jie-shi)
- [owncloud主页](https://github.com/owncloud/core)
- [owncloud客户端](https://owncloud.org/install/#install-clients)
- [owncoud docker文档](https://github.com/docker-library/docs/tree/master/owncloud)
- [phpMyAdmin docker镜像](https://github.com/phpmyadmin/docker)
- [docker-compose.yml 2写法](https://docs.docker.com/compose/compose-file/compose-file-v2/)
[owncloud](https://github.com/owncloud/core)是一款放文件和图片等数据的应用,它有点类似于网盘这样的东西,以后再也不用担心哪个网盘被封杀了,自己搭建一个,上传和下载速度又快,资料也安全,我最喜欢的是它有两个特点,第一个是有插件,比如说,我安装了一个可以写笔记的插件,还有另外一个,就是它有很多平台的客户端,在mac或windows,甚至智能手机下我可以安装一个软件,然后能够通过操作文件资源管理器那样随意同步文件。
下面是一些截图:
放文件的主页面:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/24285988f1ddc5bd613438d2648fd7b7_750x333.png)
放笔记的主页面:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/e8fe881690976eb394ed2f353c6ff1de_750x284.png)
mac下的客户端
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/d5fa18628542c1f79627e3f07c019e87_750x243.png)
这节主要还是介绍owncloud的部署,之所以会介绍phpMyAdmin的部署,是为了去研究docker的其他知识点,也能轻易地用phpMyAdmin去连接已经存在的数据库,不管是不是docker部署的。
#### 2. 部署owncloud
最简单的部署可能是这样的:
```
$ docker run -d -p 28080:80 owncloud
```
然后访问这个应用,界面如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/174f7378f4d94ce20b9c04b4c10c00e7_750x566.png)
不过这样并没有多大的用处,因为这样只能使用sqlite作为数据库,其实它可以使用mysql或postgresql作为数据库的。
我们把上一篇的知识点结合起来,最终用docker-compose来部署,写了一个部署文件:
```
version: '2'
services:
owncloud:
restart: always
image: owncloud
ports:
- 18080:80
volumes:
- /home/hfpp2012/owncloud/html:/var/www/html:Z
depends_on:
- db
dns:
- 10.202.72.118
- 10.202.72.116
- 8.8.8.8
db:
restart: always
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
- MYSQL_DATABASE=owncloud_pro
volumes:
- /home/hfpp2012/owncloud/datadir:/var/lib/mysql
```
`volumes`是挂载数据卷,这个上篇文章也说过,至于dns是为了让owncloud装插件的时候不报超时的错误。
重点来看的是`depends_on`,这个跟上篇文章所提的link是对应的。
整个意思是说这样的:这个`compose`文件包含两个服务,主要是owncloud这个服务,它又依赖于下面的db服务。也就是说这个owncloud服务可以去连接这个db数据库服务。因为这个owncloud服务是需要连接数据库的,必须要有一个数据库服务,要么是外部的,要么是内部,这里用docker开启了db服务,供owncloud来连接。
运行`docker-compose up`把这个服务跑起来。
**注意,测试的时候,建议启动前,把两个镜像卷的内容清一下**
```
$ rm -rf /home/hfpp2012/owncloud/html
$ rm -rf /home/hfpp2012/owncloud/datadir
```
启动起来后,不要再选择默认的sqlite数据库,我们要选择mysql数据库,如下所示,填上必要的信息:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/99a55c7ede9e0406183333c54db4aa81_750x1109.png)
至于最上面的管理员账号,你自己指定账号名和密码就可以了。
下面的连接数据库的配置要参照`docker-compose.yml`文件中的db部分,用户名是`root`,密码是`my-secret-pw`,数据库是`owncloud_pro`,最重要的是**数据库主机**这部分,这部分应该填写ip地址或域名的,不过这里只要填写`db`就可以了,它是一个别名,因为配置中`owncloud`中有一个项是`depends_on`,它代表能够连接到db那个容器上。
这样点击`创建完成`就能连接好数据库,整个应用也能跑起来,如下图所示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/100ba923705d190fb122b4162e5dd418_750x324.png)
#### 3. 换别的数据库postgresql
owncloud能正常跑起来,也能正常使用了,不过这里要介绍一下,如果不用mysql数据库呢,我要用postgresql,也是可以的。
把compose配置文件中的`db`那部分换一下,如下:
```
version: '2'
services:
owncloud:
restart: always
image: owncloud
ports:
- 18080:80
volumes:
- /home/ubuntu/owncloud/html:/var/www/html:Z
depends_on:
- postgresql
dns:
- 8.8.8.8
- 10.0.2.3
postgresql:
restart: always
image: sameersbn/postgresql:9.5-4
volumes:
- /home/ubuntu/owncloud/postgresql:/var/lib/postgresql:Z
environment:
- DB_USER=gitlab
- DB_PASS=password
- DB_NAME=gitlabhq_production
```
注意,此时,在owncloud安装页面中的`数据库主机`就要填成`postgresql`了。如下图所示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2c83316fd044f92cc74ea28964963546_750x1056.png)
按照之前的步骤,最后也是能正常跑起owncloud的。
#### 4. 使用phpmyadmin来连接mysql数据库
首先,我们不来连接我们之前建立的mysql服务,而是先新建一个mysql服务的容器,然后来连接。
##### 4.1 先跑起来
```
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
```
然后使用新建一个连接此mysql容器的phpmyadmin的容器:
```
$ docker run --name myadmin -d --link some-mysql:db -p 8080:80 phpmyadmin/phpmyadmin
```
打开8080端口,界面如下图所示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/89e2e2d417ac0250f60a9995f4efa80e_750x716.png)
不用填写主机,因为已经用了连接器(--link)db那个别名,用了这个别名,就会导入一些变量给myadmin这个实例,而这些变量的值,又是由`some-mysql`这个容器传过来的,例如`some-mysql`这个容器的ip地址,端口等。关于这部分的详细内容可以查看上一篇文章。
你可以试下把`db`那个名称改一下,换成别的,你会发现会用不了的,因为`myadmin`这个容器已经找不到对应的`some-mysql`容器的ip地址了。
##### 4.2 使用--net参数
使用phpmyadmin的重点不是去连接一个自己的新建的mysql服务器,这样没有意义,而是要连接我们目前存在于系统上的,且是用docker-compose部署的。
现在我们就来连接之前使用docker-compose部署owncloud时创建的mysql容器。
按照之前的经验,你可以会先找mysql容器的名称,然后把它link起来。
```
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1a069dfd65c owncloud "/entrypoint.sh ap..." 18 seconds ago Up 17 seconds 0.0.0.0:18080->80/tcp owncloud_owncloud_1
8ce43555ef6f mariadb "docker-entrypoint..." 18 seconds ago Up 18 seconds 3306/tcp owncloud_db_1
```
可见,容器名称为`owncloud_db_1`。
于是我们把phpmyadmin容器启动起来。
```
$ b3f23a98d638cd2d3a416f4692a77f56541cff44bc9c54527e9df858c348eb26
docker: Error response from daemon: Cannot link to /owncloud_db_1, as it does not belong to the default network.
```
出错了,意思是说不能连接到owncloud\_db\_1,网络不对。
确实是,之前运行owncloud容器的时候,如果你有留意到的话,它会先创建一个网络:
```
Creating network "owncloud_default" with the default driver
Creating owncloud_db_1
Creating owncloud_owncloud_1
Attaching to owncloud_db_1, owncloud_owncloud_1
...
```
我们使用`docker network ls`命令查看一下网络的情况。
```
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
80b102ef3785 bridge bridge local
925fbce49cb8 host host local
3cc70e86c6eb none null local
29f2f9c181ea owncloud_default bridge local
53afc10ba142 root_default bridge local
```
有一个适配器是由owncloud创建的,名为`owncloud_default`。我们把它利用起来。
我们在运行phpmyadmin容器的时候,加入一个参数`--net`。
```
$ docker run --name myadmin -d --link owncloud_db_1:db -p 8080:80 --net owncloud_default phpmyadmin/phpmyadmin
```
现在就可以运行起来了,记住运行前,要把以前的myadmin容器进程stop和kill掉。
##### 4.3 使用docker-compose部署
这样用命令来敲,我不太喜欢,因为难记,我喜欢把它写到一个docker-compose.yml文件中,然后一条命令就可以跑起来。
```
version: '2'
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
network_mode: "owncloud_default"
environment:
- PMA_ARBITRARY=1
restart: always
ports:
- 8080:80
volumes:
- /sessions
```
在compose配置文件中使用`network_mode`代替`--net`参数。
`PMA_ARBITRARY=1`这个是phpmyadmin使用的变量,意思就是说,可以自己输入ip地址。如下图所示:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/db11273e0119c3f3f79fe701f2350271_750x775.png)
`服务器`那里要输入`db`。
现在可以成功地用docker来运行phpmyadmin了,并且可以连接到自己需要的数据库进行查看。
至于部署到线上环境,可以参考下面这两篇文章,使用nginx反向代理过去。
- [使用compose部署gitlab应用(八)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-gitlab-ying-yong-ba)
- [使用compose部署Rocket.Chat应用(九)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-rocket-chat-ying-yong)
完结。
下一篇:[让 php-fpm 跑的 owncloud 应用 docker 化 (十二)](https://www.rails365.net/articles/php-fpm-owncloud-ying-yong-docker-shi-er-hua-shi-er)
';
10. docker 部署深入理解
最后更新于:2022-04-02 01:41:09
# 10. docker 部署深入理解
#### 1. 介绍
上一篇:[使用compose部署Rocket.Chat应用(九)](https://www.rails365.net/articles/docker-bu-shu-shen-ru-li-jie-zhi-shu-ju-ku-shi)
之所以来介绍关于数据库的部署,是因为数据库很重要,经常会被用到,也是为了下面两篇文章作铺垫。
应该说最主要是为了深入理解docker的几个概念,比如匿名卷,数据卷,网络,还有`docker-compose`的写法。
学了这些,和理解了这些知识,应该说,以后部署一个别人给你的,或网络上存在的成熟应用,是没有问题的。
#### 2. 端口映射
数据库会以mysql作为例子,postgresql等数据库是一样的。
这里有它的使用说明。
可以先看看的。
首先来思考一下,要运行一个mysql服务最基本的需求,可能是要先设置一个账号名和密码,不然如何使用呢?
所以:
运行一个最简单的mysql镜像,可以这样:
```
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
```
然后用`docker ps`查看一下,是这样的:
```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6679faa19a49 mysql "docker-entrypoint..." 3 seconds ago Up 3 seconds 3306/tcp some-mysql
```
以`mysql`镜像为基础,创建了一个容器,名为`some-mysql`,并设置`root`密码为`my-secret-pw`。
但是这个容器是没有暴露接口的,没有暴露接口的容器也是能登录的,不过需要特殊的手段,没有暴露接口,你就不能用外部的mysql等客户端来登录。
如果要暴露接口可以这么做:
```
docker run --name some-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
```
**注意,可以使用`docker stop some-mysql && docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')`来停止使用这个容器**
现在使用`docker ps`来查看一下。
```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
feab724df3b6 mysql "docker-entrypoint..." 3 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp some-mysql
```
可见,端口那个部分由`3306/tcp`变成了`0.0.0.0:3306->3306/tcp`。
`0.0.0.0`表示外部的主机能访问到。
#### 3. 环境变量
之前有说过,启动这个mysql容器的时候,已经设置了root的密码,是通过环境变量的方式设置的,也就是一个参数`-e`。
除此之外,你还可以设置其他变量:
- MYSQL\_DATABASE 指定使用的数据库,默认会创建
- MYSQL\_USER 如果不想使用root账号,可以新建一个账号来使用
- MYSQL\_PASSWORD 账号的密码
也就是说,mysql镜像会利用这些传过来的变量,来做一些操作,比如说创建数据库,创建root密码等。这样你才能去连接这个mysql服务。
#### 4. 匿名卷
我们有一个重要的功能需要注意,就是把数据库的数据保存下来,不会因为container停止了,数据就没了。
这个要用到一个叫`匿名卷`的问题。
```
# https://github.com/docker-library/mysql/blob/ee989d0666458d08dd79c55f7abb62be29a9cb3d/5.5/Dockerfile
VOLUME /var/lib/mysql
```
这个`mysql`镜像已经做好了匿名卷,就是`/var/lib/mysql`这个目录,意思就是说任何向 `/var/lib/mysql` 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。
**注意:/var/lib/mysql是容器中的路径**
当然,我们可以使用自己的目录来覆盖这个挂载设置。
使用`-v`参数即可:
```
docker run --name some-mysql -p 3306:3306 -v /home/ubuntu/owncloud/mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
```
当然你可以挂载你任何想持久化的目录和文件。
#### 5. 深入环境变量
开启了mysql服务,总要被连接或使用吧。
比如我要进去把数据导出来,可以这么做:
```
$ docker exec some-mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql
```
`$MYSQL_ROOT_PASSWORD`表示引用容器内的变量。
`MYSQL_ROOT_PASSWORD`这个变量之前有提过,在Dockerfile或一些其他启动脚本就可以先定义好,你再传进去就好了。
整条命令,表示进入容器中执行`mysqldump`命令,这个命令使用的mysql用户是`root`,连接密码,是使用是容器内部的变量`MYSQL_ROOT_PASSWORD`。
那如何来证明呢?
可以这么做:
```
$ docker exec some-mysql sh -c 'echo "$MYSQL_ROOT_PASSWORD"'
my-secret-pw
```
它会输出你之前启动mysql服务器端容器时传过去的密码:`my-secret-pw`。
我们再传一个自己的变量,然后重启开启容器:
```
$ docker run --name some-mysql -p 3306:3306 -v /home/ubuntu/owncloud/mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYENV=MYVALUE -d mysql
```
传的变量名是`MYENV`,值是`MYVALUE`。
结果输出如下:
```
$ docker exec some-mysql sh -c 'echo "$MYENV"'
MYVALUE
```
证明我们的猜想是正确的:**所以传给容器的变量都被保存着,进入容器都能使用**。
除此之外,我们还可以开启一个客户端的容器进程去连接服务器端的容器进程。
```
$ docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
```
你会发现,开启一个客户端,并且进入其中了。
这部分`--link some-mysql:mysql`先不看,我们先来看看后面的环境变量。
怎么又多出了几个变量,不过这些变量都能查看到:
```
$ docker run -it --link some-mysql:mysql --rm mysql sh -c 'env'
```
输出如下:
```
MYSQL_ENV_MYENV=MYVALUE
HOSTNAME=811b319ce670
MYSQL_MAJOR=5.7
SHLVL=0
HOME=/root
MYSQL_ENV_MYSQL_MAJOR=5.7
TERM=xterm
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
MYSQL_ENV_MYSQL_ROOT_PASSWORD=my-secret-pw
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.7.17-1debian8
MYSQL_ENV_GOSU_VERSION=1.7
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP_PROTO=tcp
MYSQL_PORT=tcp://172.17.0.2:3306
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
MYSQL_ENV_MYSQL_VERSION=5.7.17-1debian8
GOSU_VERSION=1.7
PWD=/
MYSQL_NAME=/competent_lamport/mysql
```
之前使用`MYSQL_ROOT_PASSWORD`这种变量好好的,为何又要使用`MYSQL_ENV_MYSQL_ROOT_PASSWORD`这个变量呢,原因是因为用了`--link`。
把`--link`这部分去掉再来试试。
```
$ docker run -it --rm mysql sh -c 'env'
HOSTNAME=744912e7a7f6
MYSQL_MAJOR=5.7
SHLVL=0
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.7.17-1debian8
GOSU_VERSION=1.7
PWD=/
```
看到没?少了好多变量。
想要用什么,拿来用就好了。
其中有一个变量叫`MYSQL_PORT_3306_TCP_ADDR`。
这个变量跟docker的网络接口有关。
#### 6. link和网络接口
先来看看`--link some-mysql:mysql`这个参数。
以`:`分隔分为两部分,第一部分是容器的名称,第二部是网络连接接口的别名。
表示要连接`some-mysql`这个容器,这个容器是一个mysql服务器程序,并且取了一个别名叫`mysql`,这个别名有点类似于`localhost`,有点儿像ip地址的作用,只是在容器或容器之间用。
**这个别名会发挥着很大的作用的,连接这个mysql服务器(some-mysql)的容器,都可以使用这个别名来找到这台mysql服务器的ip地址。**
下面的章节我们会介绍这个别名的使用。
我们先把这个别名改一下。
```
$ docker run -it --link some-mysql:db --rm mysql sh -c 'exec env'
HOSTNAME=ab6048fd4ccd
DB_PORT=tcp://172.17.0.2:3306
MYSQL_MAJOR=5.7
SHLVL=0
DB_PORT_3306_TCP=tcp://172.17.0.2:3306
DB_ENV_MYSQL_VERSION=5.7.17-1debian8
HOME=/root
DB_NAME=/clever_goldberg/db
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.7.17-1debian8
DB_ENV_MYSQL_MAJOR=5.7
DB_PORT_3306_TCP_ADDR=172.17.0.2
GOSU_VERSION=1.7
DB_ENV_MYSQL_ROOT_PASSWORD=my-secret-pw
PWD=/
DB_ENV_GOSU_VERSION=1.7
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
```
看下输出,之前类似以`MYSQL`开头的变量`MYSQL_PORT_3306_TCP_ADDR`的变量都变成了以`DB`开头的变量`DB_PORT_3306_TCP_ADDR`。
`DB_PORT_3306_TCP_ADDR`是个ip地址,它代表的是这台被连接的mysql服务器的容器的ip地址。
其实用一台命令也可以查出这个ip地址。
```
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
```
`container_name_or_id`表示容器的hash值,可以写上mysql服务器那个容器的名称。
比如:
```
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' some-mysql
172.17.0.2
```
果然这个地址一样的。
我们来验证一下。
进入`some-mysql`那个容器:
```
$ docker exec -it some-mysql bash
```
然后:
```
$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 9acca0e7b7f8
```
看最后一行`172.17.0.2 9acca0e7b7f8`。`9acca0e7b7f8`是`some-mysql`这个容器的hash值。
总结一下,也就是说,**如果容器要被外部使用,就要暴露接口,如果容器间使用就可以不必要暴露接口**。
下一篇文章会写关于在`docker-compose`中使用`--link`和`docker network`这个关于网络连接的指令。
完结。
下一篇:[部署owncloud与phpMyAdmin(十一)](https://www.rails365.net/articles/bu-shu-owncloud-yu-phpmyadmin-shi-yi)
';
9. 使用 compose 部署 Rocket.Chat 应用
最后更新于:2022-04-02 01:41:06
# 9. 使用 compose 部署 Rocket.Chat 应用
#### 1. 介绍
上一篇:[使用compose部署gitlab应用(八)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-gitlab-ying-yong-ba)
[Rocket.Chat](https://github.com/RocketChat/Rocket.Chat)是类似一个slack的聊天室应用,要部署它很简单,官方就有文档,只要照着那文档来即可。
它的文档地址是:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/033b06d3b6b4213f86203ab65010e45b_2190x1620.png)
#### 2. 部署
**最好切换到root账号下部署。**
第一步如下:
```
mkdir /home/rocketchat
cd /home/rocketchat
mkdir data
mkdir dump
```
接着新建docker-compose.yml文件:
```
db:
image: mongo
volumes:
- $PWD/data:/data/db
- $PWD/dump:/dump
command: mongod --smallfiles
web:
image: rocketchat/rocket.chat
environment:
- MONGO_URL=mongodb://db:27017/meteor
- ROOT_URL=http://your-ip-address:8818
links:
- db:db
ports:
- 8818:3000
```
其中`your-ip-address`改成你自己的外网的域名或ip。
用的是官方提供的docker镜像[RocketChat](https://github.com/RocketChat/Docker.Official.Image)。
然后部署:
```
$ docker-compose up
```
如果没什么问题,就使用`8818`端口访问。
最后在线上可以加上`-d`开启守护态。
#### nginx配置
最后加上nginx的反向代理配置。
```
upstream chat {
server 127.0.0.1:8818;
}
server {
listen 80;
server_name chat.rails365.net;
error_log /var/log/nginx/rocketchat.access.log;
location / {
proxy_pass http://chat/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
```
完结。
下一篇:[docker部署深入理解之数据库(十)](https://www.rails365.net/articles/docker-bu-shu-shen-ru-li-jie-zhi-shu-ju-ku-shi)
';
8. 使用 compose 部署 GitLab 应用
最后更新于:2022-04-02 01:41:04
# 8. 使用 compose 部署 GitLab 应用
#### 1. 介绍
上一篇:[Docker Compose的介绍与安装(七)](https://www.rails365.net/articles/docker-compose-de-jie-shao-yu-an-zhuang-qi)
之前介绍过compose,现在来使用它,直接来部署一个gitlab应用。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/834810744d12ae581c395c7475b2c1f5_1844x990.png)
#### 2. 下载镜像
我们部署的是[sameersbn/docker-gitlab](https://github.com/sameersbn/docker-gitlab)这个镜像。
首先把它下载下来。
```
$ docker pull sameersbn/gitlab
```
#### 3. 配置文件
我们不需要去run它,只需要先下载一个compose的配置文件。
```
$ wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml
```
打开这个文件,把它的内容按照你自己的需要修改,比如改改github登录的配置信息,邮件发送的配置信息等。
比如我的配置如下:
```
version: '2'
services:
redis:
restart: always
image: sameersbn/redis:latest
command:
- --loglevel warning
volumes:
- /srv/docker/gitlab/redis:/var/lib/redis:Z
postgresql:
restart: always
image: sameersbn/postgresql:9.5-4
volumes:
- /srv/docker/gitlab/postgresql:/var/lib/postgresql:Z
environment:
- DB_USER=gitlab
- DB_PASS=password
- DB_NAME=gitlabhq_production
- DB_EXTENSION=pg_trgm
gitlab:
restart: always
image: sameersbn/gitlab:8.15.2
depends_on:
- redis
- postgresql
ports:
- "10080:80"
- "10022:22"
volumes:
- /srv/docker/gitlab/gitlab:/home/git/data:Z
environment:
- DEBUG=false
- DB_ADAPTER=postgresql
- DB_HOST=postgresql
- DB_PORT=5432
- DB_USER=gitlab
- DB_PASS=password
- DB_NAME=gitlabhq_production
- REDIS_HOST=redis
- REDIS_PORT=6379
- TZ=Asia/Beijing
- GITLAB_TIMEZONE=Beijing
- GITLAB_HTTPS=false
- SSL_SELF_SIGNED=false
- GITLAB_HOST=gitlab.rails365.net
- GITLAB_PORT=10080
- GITLAB_SSH_PORT=10022
- GITLAB_RELATIVE_URL_ROOT=
- GITLAB_SECRETS_DB_KEY_BASE=xxx
- GITLAB_SECRETS_SECRET_KEY_BASE=xxx
- GITLAB_SECRETS_OTP_KEY_BASE=JBSWY3DPEHPK3PXP
- GITLAB_ROOT_PASSWORD=
- GITLAB_ROOT_EMAIL=
- GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
- GITLAB_NOTIFY_PUSHER=false
- GITLAB_EMAIL=hfpp2012@rails365.net
- GITLAB_EMAIL_REPLY_TO=noreply@example.com
- GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com
- GITLAB_BACKUP_SCHEDULE=daily
- GITLAB_BACKUP_TIME=01:00
- SMTP_ENABLED=true
- SMTP_DOMAIN=192.168.33.10
- SMTP_HOST=smtpdm.aliyun.com
- SMTP_PORT=25
- SMTP_USER=hfpp2012@rails365.net
- SMTP_PASS=xxxxx
- SMTP_STARTTLS=true
- SMTP_AUTHENTICATION=plain
....
- OAUTH_GITHUB_API_KEY=8910bb915c112971520b
- OAUTH_GITHUB_APP_SECRET=dc04e2fa55626bd0b1433c35adb57d85511d5772
```
有些地方被我省略了,还有些地方被我用`xxx`隐藏了。
#### 4. compose up
现在改完之后就可以直接运行了。我们使用下面的命令来运行。
```
$ docker-compose up
```
运行的时候会发现会下载其他的镜像,比如postgresql,还有redis。因为compose是允许不同的镜像容器互相链接的,从上面的配置文件中的内容也可以看出来。
如果要以守护态运行,可以加`-d`参数。
#### 5. nginx配置
这个镜像默认是会启用10080端口访问,我们可以用nginx反向代理到这个端口上。
比如:gitlab.conf。
```
upstream gitlab {
server 127.0.0.1:10080;
}
server {
listen 80;
server_name gitlab.rails365.net;
server_tokens off;
root /dev/null;
location / {
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://gitlab;
}
}
```
完结。
下一篇:[使用compose部署Rocket.Chat应用(九)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-rocket-chat-ying-yong)
';
7. Docker Compose 的介绍与安装
最后更新于:2022-04-02 01:41:02
# 7. Docker Compose 的介绍与安装
#### 1. 介绍
上一篇:[docker的数据卷(六)](https://www.rails365.net/articles/docker-de-shu-ju-juan-liu)
如果别人做了一个docker镜像服务,我最喜欢的就是它提供一个docker compose的配置文件给我,我一改,就能跑起整个应用。
docker compose能够运行容器,也就是说来实现部署,不仅如此,有时候你的应用不止一个容器,compose也能把多个容器联接起来。
#### 2. 安装
这里有官方的安装指南:
我选择用python的pip来安装,只需要一条命令即可。
```
$ sudo pip install -U docker-compose
```
如果你没有pip,那可以用下面的命令先安装一下:
```
$ sudo apt-get install python-pi
```
之后就可以直接使用`docker-compose`命令了。
除此之外,还可以从这里下载dokcer-compose的二进制文件。
复制好后要给他加上可执行权限。
完结。
下一篇:[使用compose部署gitlab应用(八)](https://www.rails365.net/articles/shi-yong-compose-bu-shu-gitlab-ying-yong)
';
6. docker 的数据卷
最后更新于:2022-04-02 01:41:00
# 6. docker 的数据卷
#### 1. 介绍
上一篇:[使用Dockerfile文件(五)](https://www.rails365.net/articles/shi-yong-dockerfile-wen-jian-wu)
之前有说过,在docker容器上进行的更改并不会主动被保存下来,除非你commit了,不然你重新运行这个镜像,生成新的容器,之前容器的内容就会没有了,因为容器只是一个进程而已。
所以说,容器运行时应该尽量保持容器存储层不发生写操作。
但是,有时候我们需要存储持久化的数据,比如数据库,你的数据都在容器中,肯定是不行的,因为一退出就没有了。
这个时候需要用到`数据卷`。
`数据卷`就是可以让你把主机上的数据以挂载的方式链接到容器中,这样不同的容器也能共享,而且数据也不会因为容器的退出而丢失。
这个`数据卷`会被经常使用。
#### 2. 使用
下面我们来体会一下`数据卷`的功能。
```
$ docker run -d -v ~/mynginx:/a -p 80:80 --name webserver nginx
```
这里命令会挂载主机的目录`~/mynginx`到容器中的目录`/a`。
你可以试验一下,分别在两端更改内容,比如新建一个文件,看是不是都变化了。
我们也可以创建数据卷容器,数据卷容器也是一个正常的容器,这种容器可以为其他容器提供和共享数据。
比如,下面创建了一个数据卷容器:
```
$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
```
然后其他容器要使用这个数据卷容器的话,只要使用`--volumes-from`参数即可。
```
$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
```
完结。
下一篇:[Docker Compose 的介绍与安装 (七)](https://www.rails365.net/articles/docker-compose-de-jie-shao-yu-an-zhuang-qi)
';
5. 使用 Dockerfile 文件
最后更新于:2022-04-02 01:40:57
# 5. 使用 Dockerfile 文件
#### 1. 介绍
上一篇:[理解docker镜像的层叠结构(四)](https://www.rails365.net/articles/li-jie-docker-jing-xiang-de-ceng-die-jie-gou-si)
Dockerfile是一个纯文本文件,内容是可读的,就是把构建镜像的指令一条条放在这个文件中,然后就可以build出来一个镜像。
#### 2. 使用
我们来实践一下。
创建一个最简单的Dockerfile文件。
```
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile
```
内容如下:
```
FROM nginx
RUN echo ' 6fb1fd56e2dd 4 seconds ago 182 MB
nginx v2 f51e5af097aa 44 minutes ago 182 MB
```
其中可看出,`REPOSITORY`和`TAG`部分都为none,其实我们build的时候可以给个名称标识一下。
```
$ docker build -t nginx:v3 .
```
现在就有了。
```
$ docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 6fb1fd56e2dd 4 minutes ago 182 MB
nginx v2 f51e5af097aa 48 minutes ago 182 MB
```
#### 3. 参数解释
回到之前的Dockerfile文件的内容。
```
FROM nginx
RUN echo '
完结。
下一篇:[docker的数据卷(六)](https://www.rails365.net/articles/docker-de-shu-ju-juan-liu)
';
Hello, Docker!
' > /usr/share/nginx/html/index.html ``` 我们以此Dockerfile文件,来生成了一个镜像,使用`docker build`命令。 只要 ``` $ docker build . ``` 会显示这样的信息: ``` Sending build context to Docker daemon 2.048 kB Step 1/2 : FROM nginx ---> db079554b4d2 Step 2/2 : RUN echo 'Hello, Docker!
' > /usr/share/nginx/html/index.html ---> Running in 64127d3ff089 ---> 6fb1fd56e2dd Removing intermediate container 64127d3ff089 Successfully built 6fb1fd56e2dd ``` build成功之后可以查看一下: ``` $ docker images nginx REPOSITORY TAG IMAGE ID CREATED SIZEHello, Docker!
' > /usr/share/nginx/html/index.html ``` 只有两个指令,分别是`FROM`和`RUN`。 `FROM`代表的是基础镜像,`RUN`表示的是运行的命令。 值得注意的是,每条指令都会创建一层镜像,不要单独写太多的`RUN`语句,而是要串起来。 例如,类似下面的作法是不对的。 ``` FROM ruby:2.2.2 # update RUN apt-get update -qq # RUN apt-get upgrade -qq # RUN apt-get dist-upgrade -qq # RUN apt-get autoremove -qq # for build essential lib RUN apt-get install -y build-essential # for postgres RUN apt-get install -y libpq-dev # for nokogiri RUN apt-get install -y libxml2-dev libxslt1-dev # for a JS runtime RUN apt-get install -y nodejs # for imagemagick RUN apt-get install -y imagemagick # for vim RUN apt-get install -y vim # set gem sources RUN gem sources -r https://rubygems.org/ RUN gem sources -a https://ruby.taobao.org/ ENV APP_HOME /var/www/coomo_store RUN mkdir -p $APP_HOME WORKDIR $APP_HOME ADD Gemfile* $APP_HOME/ RUN bundle install --jobs=4 ADD . $APP_HOME ``` 还有很多命令,会被经常用到,比如`ARG`, `ENV`, `EXPOSE`, `WORKDIR`, `CMD`。 下面来介绍一下。 `ARG`表示的是设置一个参数,在build的时候由外面通过命令行参数的形式传过来。 比如: ``` $ docker build --build-arg PORT=3000 --build-arg NPM_TOKEN=e43d3f2c-e7b7-4522-bf74-b7d2863eddf7 . ``` 传了两个参数分别为`PORT`和`NPM_TOKEN`。 `ENV`是设置环境变量,以后这个变量可以传到docker容器内部中去。 `EXPOSE`表示暴露的端口号。 `WORKDIR`就是指定工作目录啦。 `CMD`是容器启动的命令。 来看一个实例,具体体会一下这些命令。 ``` from node:6.9 ARG PORT ARG NPM_TOKEN ENV PORT ${PORT} ENV NPM_TOKEN ${NPM_TOKEN} EXPOSE ${PORT} ADD . /code WORKDIR /code RUN npm install RUN npm run build CMD npm run docker ``` 下面这个链接是官方给的关于Dockerfile的文档:4. 理解 docker 镜像的层叠结构
最后更新于:2022-04-02 01:40:55
# 4. 理解 docker 镜像的层叠结构
#### 1. 介绍
上一篇: [docker的容器(三)](https://www.rails365.net/articles/docker-de-rong-qi-san)
可能你使用`docker pull sameersbn/gitlab`命令的时候,会发现要下载好多images,因为docker的images是层叠结构的。
这个有点像git。就是最上一层的images,可能是下一层的images,为基础构建的。
#### 2. docker commit
要先理解这个,先来看个例子。
之前我们使用过下面的命令来运行过一个nginx服务。
```
$ docker run --name webserver -d -p 80:80 nginx
```
现在我们进入到这个容器,改点东西。
```
$ docker exec -it webserver bash
```
然后:
```
root@3729b97e8226:/# echo '" \
--message "修改了默认网页" \
webserver \
nginx:v2
```
现在来查看一下nginx的镜像,发现有两个,如下:
```
$ docker images nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 f51e5af097aa 5 minutes ago 182 MB
nginx latest db079554b4d2 11 days ago 182 MB
```
因为v2那个版本的nginx镜像,才只是改一点点内容,所以他们两个镜像的占用磁盘的容量只是182MB多点,而不是182 \* 2 MB。
现在可以把v2这个版本的nginx镜像运行起来。
```
$ docker run --name web2 -d -p 81:80 nginx:v2
```
#### 3. 慎用 docker commit
使用`docker commit`虽然能保存镜像或创建镜像,但是一般情况下我们不会这么用,我们会使用`Dockerfile`来构建镜像。
`docker commit`有一些不好的地方,上面的例子也可以看出来,我只是改了一个文件,上面却显示改了很多,比如临时文件,记录命令的文件(.bash\_history),还有pid文件啥的。
而且使用`docker commit`创建的镜像,别人也不无法知道你是如何创建的,万一里面藏着什么东西,别人都不知道,很不安全。
所以嘛,我们接下来会使用`Dockerfile`来创建镜像。
完结。
下一篇:[使用Dockerfile文件(五)](https://www.rails365.net/articles/shi-yong-dockerfile-wen-jian-wu)
';
Hello, Docker!
' > /usr/share/nginx/html/index.html root@3729b97e8226:/# exit ``` 你再使用`curl http://localhost`看看,是不是页面变了。 然后你再使用stop命令把这个容器停掉,然后再启动,你会发现又变回原来的样子。 我们之前修改了容器的内容。 来看看改了哪些东西: ``` $ docker diff webserver C /root A /root/.bash_history C /run A /run/nginx.pid C /usr C /usr/share C /usr/share/nginx C /usr/share/nginx/html C /usr/share/nginx/html/index.html C /var C /var/cache C /var/cache/nginx A /var/cache/nginx/client_temp A /var/cache/nginx/fastcgi_temp A /var/cache/nginx/proxy_temp A /var/cache/nginx/scgi_temp A /var/cache/nginx/uwsgi_temp ``` 我们可以把这个容器的改变保存下来,成为一个镜像,下次就能直接运行了。 ``` $ docker commit \ --author "hfpp20123. docker 的容器
最后更新于:2022-04-02 01:40:53
# 3. docker 的容器
#### 1. 介绍
上一篇:[docker的镜像和镜像源加速(二)](https://www.rails365.net/articles/docker-de-jing-xiang-he-jing-xiang-yuan-jia-su-er)
之前我们下载了`hello-world`这个镜像,现在把它运行起来。
使用`docker run`命令。
比如:
```
$ docker run hello-world
```
主要是输出一些文本信息,然后就退出了。
使用`docker ps`可以查看容器的进程。
不过是空的,因为一运行就退出,只是输出信息,输出完就结束了。
可以使用`docker ps -a`来查看退出过的进程。
比如:
```
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b25a96c17bf4 hello-world "/hello" About a minute ago Exited (0) About a minute ago mystifying_saha
```
#### 2. 运行容器
上面只是演示hello world而已,我们运行些有用点的容器。
比如:
```
$ docker run -it ubuntu bash
```
运行的是ubuntu这个镜像,如果你的系统上没有这个镜像,会先下载下来。
`bash`是表示进入那个ubuntu的镜像的容器的shell,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。
这样就相当于进入了另一台ubuntu。
而且这个ubuntu跟你原来的系统是隔离的。
这样也没多大意义,我们经常会用docker来跑一些服务,比如web服务。
那就运行一个nginx容器试试。
```
$ docker run -d -p 80:80 --name webserver nginx
```
镜像名称是`nginx`,`--name`表示为这个容器取个名称叫`webserver`。
运行之后,你用`docker ps`查看一下容器。
```
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1d4b615709b nginx "nginx -g 'daemon ..." 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, 443/tcp webserver
```
然后你可以使用`curl http://127.0.0.1`查看一下,是否运行了nginx服务。
使用`docker stop`命令可以停止这个容器的运行。
比如:
```
$ docker stop webserver
```
停止之后输入`docker ps`发现是空的,这个时候要输入`docker ps -a`才能查看退出的容器。
可以使用下面这条命令,清除所有已退出的容器。
```
$ docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')
```
之前运行nginx容器的时候,有使用`-p 80:80`这个参数。
这个表示端口映射。
解释前,我们先来改一下。
```
$ docker run -d -p 8080:80 --name webserver nginx
```
查看一下运行状态:
```
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45e47ed889f8 nginx "nginx -g 'daemon ..." 4 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:8080->80/tcp webserver
```
现在你可以需要使用`curl http://127.0.0.1:8080`才能访问了。
也就是说,`-p`参数中,第一个端口是暴露在外面的端口,外面可以访问的端口。
至于`-d`嘛,就是以守护态运行。
有些应用根本就不需要暴露接口在外面,比如下面这个:
```
$ docker ps
mposenginx_gitlab_1
7e4493b736d2 sameersbn/postgresql:9.5-4 "/sbin/entrypoint.sh" 2 days ago Up 2 days 5432/tcp gitlabcomposenginx_postgresql_1
8cd6c90f9a52 sameersbn/redis:latest "/sbin/entrypoint.sh " 2 days ago Up 2 days 6379/tcp
```
这两个端口在外部是无法访问的,没有绑定在0.0.0.0这个ip上,这个有什么用呢。
其实有个参数是`--link`,供单机的容器之间打通一个网络通道,这样不必通过ip来访问,而是一个别名。
比如,先运行两个容器:
```
$ docker run --name gitlab-postgresql -d \
--env 'DB_NAME=gitlabhq_production' \
--env 'DB_USER=gitlab' --env 'DB_PASS=password' \
--env 'DB_EXTENSION=pg_trgm' \
--volume /srv/docker/gitlab/postgresql:/var/lib/postgresql \
sameersbn/postgresql:9.6-2
$ docker run --name gitlab-redis -d \
--volume /srv/docker/gitlab/redis:/var/lib/redis \
sameersbn/redis:latest
```
这两个容器有两个名称,分别是`gitlab-postgresql`和`gitlab-redis`。
然后再启动一个暴露接口的容器,去连接这两个容器。
```
$ docker run --name gitlab -d \
--link gitlab-postgresql:postgresql --link gitlab-redis:redisio \
--publish 10022:22 --publish 10080:80 \
--env 'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' \
--env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' \
--env 'GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alpha-numeric-string' \
--env 'GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alpha-numeric-string' \
--volume /srv/docker/gitlab/gitlab:/home/git/data \
sameersbn/gitlab:8.16.6
```
其中`postgresql`和`redisio`是容器的主机别名。
使用`docker restart`命令可以重启容器。
还有一个参数比较常用,就是`-rm`,这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm 。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。
完结。
下一篇: [理解docker镜像的层叠结构(四)](https://www.rails365.net/articles/li-jie-docker-jing-xiang-de-ceng-die-jie-gou)
';
2. docker 的镜像和镜像源加速
最后更新于:2022-04-02 01:40:51
# 2. docker 的镜像和镜像源加速
#### 1. 介绍
上一篇: [安装docker(一)](https://www.rails365.net/articles/an-zhuang-docker-yi)
说镜像前,先说说容器,其实容器就是在镜像上运行的进程,docker容器就是一个个进程,就好比,镜像是模板,存在于磁盘上,而容器就是模板生成来的实例,就有点类似,镜像是类,而对象是容器,对象是类生成的。
先来查看系统上的镜像,可以使用`docker images`命令。
你会发现是空的。
因为没有任何镜像。
我们来做个`hello world`。
首先要下载镜像,会使用`docker pull`命令,比如:
```
$ docker pull hello-world
```
你可能会发现,半天都没反应,更没下载下来,因为那个放镜像的地方在国外,反正在国内访问就有点慢,所以需要用到加速器。
#### 2. 加速器
已经有人同步好了那些镜像,放在了国内的服务器,我们下载下来就会快很多。
这个就是加速器。
国内的加速器有好多,我们使用阿里云的加速器。
把下面的内容贴到终端上:
```
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://oyukeh0j.mirror.aliyuncs.com"]
}
EOF
```
然后再把docker重启,比如我是ubuntu 14.04,就可以这样:
```
$ sudo /etc/init.d/docker restart
```
你再运行`docker pull hello-world`试试。
是不是很快?
如果看不出效果,可以试下`docker pull sameersbn/gitlab`
上面说的是在ubuntu下进行操作,如果是mac呢?
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/745d626c2fa730412d0c48b9694566ab_750x1042.png)
完结。
下一篇:[docker的容器(三)](https://www.rails365.net/articles/docker-de-rong-qi-san)
';
1. 安装 docker
最后更新于:2022-04-02 01:40:48
# 1. 安装 docker
#### 1. 介绍
docker有点像虚拟机技术那样,虚拟机是模拟了全部或部分的硬件,有一整套自己的操作系统,而docker不是,它只是一个进程,这个进程叫容器,这种叫容器技术,或隔离技术,它没有再启动一个操作系统,因为太耗资源,又太慢,它是隔离了linux内核,有自己的空间,比如说,自己的root账号,磁盘情况等。它很轻量极,启动很快,一个机器可以启动很多个docker容器进程。
说说几个应用场景,你没有理由不去用它。
- 前端工程师,不懂配置php或java的开发环境
- 持续集成测试
- 快速部署,一条命令,部署的环境一模一样
- 作为一个nodejs程序员,不懂php或ruby,想部署它们写的应用,一条命令
- 方便地对程序进行资源配置,比如进程监控,内存限制
- 安装软件太慢,比如安装mongodb,要下载下来要好久,而docker只需要一条命令就可以跑起来
#### 2. mac下安装
点击[这里](https://docs.docker.com/docker-for-mac/install/)下载最新的mac版安装程序。
点击安装包下载完,运行即可。
#### 3. linux下安装
一条命令即可。
```
curl -sSL https://get.daocloud.io/docker | sh
```
**这条命令在ubuntu 14.04和ubuntu 16.04都可以成功安装docker。**
安装完成功后,可能会提示你这样的信息:
```
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker vagrant
Remember that you will have to log out and back in for this to take effect!
```
`vagrant`是你的用户名,可能你的用户名跟我的不一样。
意思就是说,你可以把当前用户加入到docker组,以后要管理docker就方便多了,不然你以后有可能要使用docker命令前,要在前面加`sudo`。
如果没加`sudo`就是类似这样的提示:
```
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/json: dial unix /var/run/docker.sock: connect: permission denied
```
不过执行了`sudo usermod -aG docker vagrant`之后,你再重新登录(ssh),就可以免去加`sudo`。
安装成功,需要把docker这个服务启动起来:
如果是ubuntu 14.04的系统,它会自动启动,你也可以使用下面的命令来启动。
```
$ sudo /etc/init.d/docker start
```
如果是ubuntu 16.04的系统,就用下面的命令:
```
$ sudo systemctl status docker.service
```
完结。
下一篇:[docker的镜像和镜像源加速(二)](https://www.rails365.net/articles/docker-de-jing-xiang-he-jing-xiang-yuan-jia-su-er)
';
0. 介绍
最后更新于:2022-04-02 01:40:46
# 0. 介绍
# docker 入门指南
零基础学习docker,从应用入手带你深入理解docker。
原文发布于我的个人博客:
源码位于:
电子版: [PDF](https://www.gitbook.com/download/pdf/book/yinsigan/docker) [Mobi](https://www.gitbook.com/download/mobi/book/yinsigan/docker) [ePbu](https://www.gitbook.com/download/epub/book/yinsigan/docker)
### 联系我:
email: hfpp2012@gmail.com
qq: 903279182
';