Docker # Producción de imágenes de contenedor de Dockfile

Gestión de contenedores de Docker y producción de imágenes

Gestión de contenedores de Docker y producción de imágenes
1: Cree su propia imagen
1. Empaquete
el sistema de archivos del contenedor en un paquete tar Empaquete el sistema de archivos del contenedor en un archivo tar, es decir, exporte directamente el contenedor en ejecución como un archivo de imagen del paquete tar.
Exportar:

export    
    Export a container's filesystem as a tar archive
有两种方式(elated_lovelace为容器名):
第一种:
docker export -o elated_lovelace.tar elated_lovelace
第二种:
docker export 容器名称 > 镜像.tar

Importar:

导入镜像归档文件到其他宿主机:
import    
    Import the contents from a tarball to create a filesystem image
docker import elated_lovelace.tar  elated_lovelace:v1 

Nota:
Si no hay un nombre al importar la imagen, puede nombrarla por separado (sin nombre y etiqueta) y puede agregar etiquetas manualmente.

docker tag 镜像ID mycentos:7 

2. Migración de imágenes
Guarde la imagen en un host como un archivo tar y luego impórtelo a otros hosts.

save      
    Save an image(s) to a tar archive
    将镜像打包,与下面的load命令相对应
[root@xingdian ~]# docker save -o nginx.tar nginx
load      
    Load an image from a tar archive or STDIN
    与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入
docker load < nginx.tar

Nota:
1. El nombre del archivo tar no tiene nada que ver con el nombre de la imagen guardada
. 2. Si la imagen importada no tiene un nombre, etiquételo usted mismo.
Extensión: la diferencia entre
exportar y guardar. Exportar: equivalente a una instantánea de contenedor. El archivo de instantánea de contenedor descartará todos
Guarde el historial y la información de los metadatos : Si no existe tal fenómeno, está completo.
3. Cree una imagen local a través del contenedor.
Fondo: Una vez que el
contenedor se está ejecutando, se realizan algunas operaciones en él, y los resultados de la operación deben guardarse en la imagen.
Solución:
use el comando docker commit para enviar directamente un contenedor en ejecución como una imagen. Confirmar significa enviar, similar a decirle al servidor svn que quiero generar una nueva versión.
Ejemplo:
crear un nuevo archivo dentro del contenedor

[root@xingdian ~]# docker exec -it 4ddf4638572d /bin/sh  
root@4ddf4638572d:/app# touch test.txt
root@4ddf4638572d:/app# exit
#  将这个新建的文件提交到镜像中保存
[root@xingdian ~]# docker commit 4ddf4638572d xingdian/helloworld:v2

ejemplo:

[root@xingdian ~]# docker commit -m "my images version1" -a "xingdian" 108a85b1ed99 daocloud.io/ubuntu:v2
sha256:ffa8a185ee526a9b0d8772740231448a25855031f25c61c1b63077220469b057
    -m                        添加注释
    -a                        作者
    108a85b1ed99              容器环境id
    daocloud.io/ubuntu:v2     镜像名称:hub的名称/镜像名称:tag 
    -p,–pause=true           提交时暂停容器运行

Dos: use Dockerfile para crear
un espejo Aunque puede crear un rootfs (sistema de archivos raíz) usted mismo, Docker proporciona una forma más conveniente, llamada Dockerfile.
El comando docker build se usa para crear una imagen de Docker basada en el Dockerfile y el contexto dados.
sintaxis de compilación de Docker

[root@xingdian ~]# docker build [OPTIONS] <PATH | URL | ->
  1. Descripción de opciones comunes
    –build-arg, establece la variable durante la compilación
    –no-cache, por defecto es falso. Establecer esta opción no usará Build Cache para construir la imagen
    , el valor predeterminado es falso. Establezca esta opción, siempre intente extraer la última versión de
    image-compress, el valor predeterminado es falso. La configuración de esta opción usará la compresión gzip para construir el contexto
    -disable-content-trust, el valor predeterminado es verdadero. Al establecer esta opción se verificará la imagen
    –archivo, -f, la ruta completa del Dockerfile, el valor predeterminado es '
    PATH / Dockerfile' –isolation, el predeterminado –isolation = “default”, es decir, el espacio de nombres de Linux; hay otros procesos o hiperv -Label,
    establezca metadatos
    -squash para la imagen generada , el valor predeterminado es falso. Configure esta opción para comprimir las capas múltiples recién construidas en una nueva capa, pero la nueva capa no se puede compartir entre varias imágenes; configurar esta opción crea una nueva imagen mientras conserva la imagen original.
    --Tag, -t, el nombre y la etiqueta de la imagen, generalmente en nombre: etiqueta o formato de nombre; puede establecer varias etiquetas para una imagen en una
    red de compilación , el valor predeterminado es predeterminado. Establezca esta opción, Establezca el modo de red para las instrucciones RUN durante la compilación
    -quiet, -q, el valor predeterminado es falso. Establezca esta opción, suprima la salida de compilación e imprima la ID de la imagen en caso de éxito
    --Force-rm, el valor predeterminado es falso. Establezca esta opción, elimine siempre el contenedor intermedio
    -rm, el valor predeterminado -rm = true, es decir, elimine el contenedor intermedio después de que todo el proceso de compilación sea exitoso
  2. PATH | URL | -Description
    Da el contexto de ejecución del comando.
    El contexto puede ser la ruta local donde se ejecuta la compilación, o puede ser una URL remota, como una biblioteca Git, tarball o archivo de texto. Si se trata de una biblioteca de Git, como https://github.com/docker/rootfs.git#container:docker, ejecute implícitamente git clone --depth 1 --recursive primero en el directorio temporal local; luego en el directorio temporal Enviado al proceso de construcción.
    En el proceso de construcción de la imagen, cualquier archivo en el contexto (tenga en cuenta que el archivo debe estar en el contexto) se puede agregar a la imagen mediante el comando ADD.
    -Indica que el Dockerfile o contexto se da a través de STDIN.
    Ejemplo:
[root@xingdian ~]#  docker build - < Dockerfile

Nota: El proceso de compilación solo tiene un Dockerfile sin contexto

Descripción: el Dockerfile se encuentra en la ruta raíz de context.tar.gz

[root@xingdian ~]# docker build -t champagne/bbauto:ltest -t champagne/bbauto:v2.1 .
[root@xingdian ~]# docker build -f dockerfiles/Dockerfile.debug -t myapp_debug .

  1. Cree la carpeta donde se encuentra la imagen y el
    comando Dockerfile :
mkdir sinatra 
cd sinatra 
touch Dockerfile 
  1. Escriba instrucciones en el archivo Dockerfile y cada instrucción actualizará la información de la imagen
# This is a comment 
FROM daocloud.io/library/ubuntu 
MAINTAINER xingdian [email protected]
RUN apt-get update && apt-get install -y ruby ruby-dev 

Descripción del formato:
cada línea de comando tiene la forma de instrucción INSTRUCTION, que es el modo de comando + lista. Los comandos deben estar en mayúscula, "#" es un comentario.
El comando FROM le dice a Docker cuál es nuestra imagen.
MAINTAINER es el creador de la imagen descriptiva.
El comando RUN se ejecuta dentro del espejo. Es decir, los comandos detrás de él deben ser comandos que se puedan ejecutar para duplicar.
5. Cree un
comando de espejo :

docker build -t xingdian/sinatra:v2 .

docker build es el comando para que docker cree un espejo
-t es para identificar el espejo recién creado
sinatra es el nombre del almacén
: v2 es la etiqueta
"." se usa para indicar el
proceso de ejecución detallado del directorio actual del archivo Dockerfile que usamos :

 [root@master sinatra]# docker build -t xingdian/sinatra:v2 . 
        Sending build context to Docker daemon 2.048 kB
        Step 1 : FROM daocloud.io/ubuntu:14.04
        Trying to pull repository daocloud.io/ubuntu ... 
        14.04: Pulling from daocloud.io/ubuntu
        f3ead5e8856b: Pull complete 
        Digest: sha256:ea2b82924b078d9c8b5d3f0db585297a5cd5b9c2f7b60258cdbf9d3b9181d828
         ---> 2ff3b426bbaa
        Step 2 : MAINTAINER xingdian [email protected]
         ---> Running in 948396c9edaa
         ---> 227da301bad8
        Removing intermediate container 948396c9edaa
        Step 3 : RUN apt-get update && apt-get install -y ruby ruby-dev
         ...
        Step 4 : RUN gem install sinatra
        ---> Running in 89234cb493d9

6. Una vez completada la creación, cree un contenedor a partir de la imagen.

[root@xingdian ~]# docker run -t -i xingdian/sinatra:v2 /bin/bash

Tres: Comprender el problema del sistema de archivos contenedor (lectura y comprensión extracurricular)
:
la función del espacio de nombres es "aislamiento", permite que el proceso de aplicación solo vea el "mundo" en el espacio de nombres; y el papel de Cgroups es "restricción", le da esto " El mundo "encierra un muro invisible. Después de tal lanzamiento, el proceso realmente se "instala" en una habitación aislada, y estas habitaciones son la "caja de arena" de la aplicación de la que depende el proyecto PaaS.
Sin embargo, hay otra pregunta: aunque hay paredes alrededor de esta habitación, ¿qué pasa si el proceso del contenedor mira hacia el suelo?
En otras palabras, ¿cuál es el sistema de archivos que ve el proceso en el contenedor?
Tal vez pueda pensar inmediatamente que esto debe ser un problema con Mount Namespace: el proceso de aplicación en el contenedor debería ver un sistema de archivos completamente independiente. De esta manera, puede operar bajo su propio directorio de contenedores (como / tmp) sin verse afectado por la máquina host y otros contenedores.
Entonces, ¿es esto cierto?
Un programa pequeño: la función es abrir el espacio de nombres especificado al crear un proceso hijo. Úselo para verificar el problema que se acaba de mencionar.

#define _GNU_SOURCE
#include <sys/mount.h> 
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#define STACK_SIZE (1024 * 1024)
static char container_stack[STACK_SIZE];
char* const container_args[] = {
    
    
  "/bin/bash",
  NULL
};
int container_main(void* arg)
{
    
      
  printf("Container - inside the container!\n");
  execv(container_args[0], container_args);
  printf("Something's wrong!\n");
  return 1;
}
int main()
{
    
    
  printf("Parent - start a container!\n");
  int container_pid = clone(container_main, container_stack+STACK_SIZE, CLONE_NEWNS | SIGCHLD , NULL);
  waitpid(container_pid, NULL, 0);
  printf("Parent - container stopped!\n");
  return 0;
}

La función de código es muy simple: en la función principal, se crea un nuevo proceso hijo container_main a través de la llamada al sistema clone (), y se declara para habilitar Mount Namespace (es decir: bandera CLONE_NEWNS).
Y lo que ejecuta este proceso hijo es un programa "/ bin / bash", que es un shell. Entonces, este shell se ejecuta en el entorno de aislamiento de Mount Namespace.
Compila este programa:

[root@xingdian ~]# gcc -o ns ns.c
[root@xingdian ~]# ./ns
Parent - start a container!
Container - inside the container!

De esta manera, ingresa a este "contenedor" (no es grande en la nota superficial-xingdiana). Sin embargo, si ejecuta el comando ls en el "contenedor", encontrará un fenómeno interesante: el contenido del directorio / tmp es el mismo que el contenido del host.

[root@xingdian ~]# ls /tmp
# 你会看到好多宿主机的文件

En otras palabras:
incluso si Mount Namespace está habilitado, el sistema de archivos visto por el proceso del contenedor es exactamente el mismo que el host.
¿Que esta pasando aqui?
Si lo piensa detenidamente, encontrará que en realidad no es difícil de entender: Mount Namespace modifica la percepción del "punto de montaje" del sistema de archivos por el proceso contenedor. Sin embargo, esto también significa que la vista del proceso solo se cambiará después de que se haya producido la operación de "montaje". Antes de eso, el contenedor recién creado hereda directamente los distintos puntos de montaje del host.
En este momento, es posible que haya pensado en una solución: al crear un nuevo proceso, además de declarar para habilitar Mount Namespace, también puede decirle al proceso contenedor qué directorios deben volver a montar, como este directorio / tmp. Por lo tanto, puede agregar un paso para volver a montar el directorio / tmp antes de que se ejecute el proceso del contenedor:

int container_main(void* arg)
{
    
    
  printf("Container - inside the container!\n");
  // 如果你的机器的根目录的挂载类型是 shared,那必须先重新挂载根目录
  // mount("", "/", NULL, MS_PRIVATE, "");
  mount("none", "/tmp", "tmpfs", 0, "");
  execv(container_args[0], container_args);
  printf("Something's wrong!\n");
  return 1;
}

En el código modificado, antes de que comience el proceso del contenedor, se agrega una instrucción mount ("none", "/ tmp", "tmpfs", 0, ""). De esta manera, dígale al contenedor que vuelva a ingresar container_main (void * arg) en formato tmpfs (disco de memoria)

{
    
      
  printf("Container - inside the container!\n");
  execv(container_args[0], container_args);
  printf("Something's wrong!\n");
  return 1;
}新挂载了 /tmp 目录。

¿Qué pasa con el resultado de compilar y ejecutar el código modificado? Pruébalo:

[root@xingdian ~]# gcc -o ns ns.c
[root@xingdian ~]# ./ns
Parent - start a container!
Container - inside the container!
[root@xingdian ~]# ls /tmp
这次 /tmp 变成了一个空目录,这意味着重新挂载生效了。
用 mount -l 检查:
[root@xingdian ~]# mount -l | grep tmpfs
none on /tmp type tmpfs (rw,relatime)

El directorio / tmp del contenedor se monta individualmente en modo tmpfs. Puede desinstalar el directorio / tmp para ver el efecto.
Más importante aún, debido a que el proceso recién creado tiene habilitado Mount Namespace, la operación de remontaje solo es válida en el Mount Namespace del proceso contenedor. Si marca este montaje con mount -l en el host, encontrará que no existe:
en el host

[root@xingdian ~]# mount -l | grep tmpfs

Aquí es donde Mount Namespace es ligeramente diferente de otros espacios de nombres: sus cambios en la vista del proceso del contenedor deben ir acompañados de una operación de montaje (mount) para que surtan efecto.
Lo que esperamos es: siempre que se crea un nuevo contenedor, quiero que el sistema de archivos visto por el proceso del contenedor sea un entorno de aislamiento independiente, no un sistema de archivos heredado del host. ¿Cómo se puede hacer esto?
El directorio raíz completo "/" se puede volver a montar antes de que comience el proceso del contenedor. Y debido a la existencia de Mount Namespace, este montaje no es visible para el host, por lo que el proceso del contenedor puede incluirlo.
En el sistema operativo Linux, hay un comando llamado chroot que puede ayudarlo a realizar esta tarea cómodamente en el shell. Como sugiere el nombre, su función es ayudarlo a "cambiar el sistema de archivos raíz", es decir, cambiar el directorio raíz del proceso a la ubicación que especifique.
Supongamos que hay un directorio / home / xingdian / test y quiero usarlo como directorio raíz de un proceso / bin / bash.
Primero, cree un directorio de prueba y varias carpetas lib:

[root@xingdian ~]# mkdir -p /home/xingdian/test
[root@xingdian ~]# mkdir -p /home/xingdian/test/{bin,lib64,lib}
然后,把 bash 命令拷贝到 test 目录对应的 bin 路径下:
# cp -v /bin/{bash,ls}  /home/xingdian/test/bin

A continuación, copie todos los archivos so requeridos por los comandos ls y bash a la ruta lib correspondiente al directorio de prueba. Puede usar el comando ldd para encontrar el archivo so: (ldd enumera bibliotecas dependientes dinámicas)


```bash
[root@xingdian ~]# list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"
[root@xingdian ~]# for i in $list; do cp -v "$i" "/home/xingdian/test/${i}"; done
[root@xingdian ~]# list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')"
[root@xingdian ~]# for i in $list; do cp -v "$i" "/home/xingdian/test/${i}"; done

最后,执行 chroot 命令,告诉操作系统,将使用 /home/xingdian/test 目录作为 /bin/bash 进程的根目录:

```bash
[root@xingdian ~]# chroot /home/xingdian/test /bin/bash

En este momento, ejecute "ls /" y verá que devuelve todo el contenido del directorio / home / xingdian / test, no el contenido del host.
Más importante aún, para el proceso chroot, no sentirá que su directorio raíz ha sido "modificado" a / home / xingdian / test.
¿Es el principio de modificación de esta vista similar al espacio de nombres de Linux que presenté anteriormente?
De hecho, Mount Namespace se inventó sobre la base de la mejora continua de chroot y es también el primer espacio de nombres en el sistema operativo Linux.
Para que el directorio raíz del contenedor parezca más "real", generalmente se monta un sistema de archivos de un sistema operativo completo, como el ISO de Ubuntu 16.04, bajo el directorio raíz del contenedor. De esta manera, después de que se inicie el contenedor, ejecute "ls /" en el contenedor para ver el contenido del directorio raíz, que son todos los directorios y archivos de Ubuntu 16.04.
Y este sistema de archivos, que se monta en el directorio raíz del contenedor y se utiliza para proporcionar un entorno de ejecución aislado para el proceso del contenedor, es la denominada "imagen del contenedor". También tiene un nombre más profesional, llamado: rootfs (sistema de archivos raíz).
Por lo tanto, una imagen de contenedor o rootfs más común incluirá algunos directorios y archivos como se muestra a continuación, como / bin, / etc, / proc, etc .:

[root@xingdian ~]# ls /
bin dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var

El / bin / bash que se ejecuta después de ingresar al contenedor es el archivo ejecutable en el directorio / bin, que es completamente diferente del / bin / bash del host.
Por lo tanto, para el proyecto Docker, su principio básico es en realidad que se cree el proceso de usuario:
1. Habilitar la configuración del espacio de nombres de Linux,
2. Establecer los parámetros de Cgroups especificados,
3. Cambiar el directorio raíz del proceso (Cambiar raíz).
De esta forma nació un contenedor completo. Sin embargo, el proyecto Docker dará prioridad a la llamada al sistema pivot_root en el último paso del cambio. Si el sistema no lo admite, se utilizará chroot. Las funciones de estas dos llamadas al sistema son similares a
rootfs y kernel:
rootfs son solo los archivos, configuraciones y directorios contenidos en un sistema operativo, y no incluyen el kernel del sistema operativo. Todos los contenedores en la misma máquina comparten el kernel del sistema operativo host. Si su aplicación necesita configurar parámetros del kernel, cargar módulos de kernel adicionales e interactuar directamente con el kernel, debe prestar atención: estas operaciones y objetos dependientes son el kernel del sistema operativo host, que es para la máquina Para todos los contenedores anteriores, es una "variable global" que afecta a todo el cuerpo.
En el sistema operativo Linux, estas dos partes se almacenan por separado y el sistema operativo solo cargará la versión especificada de la imagen del kernel cuando se inicie.
Esta es una de las deficiencias de los contenedores en comparación con las máquinas virtuales: las máquinas virtuales no solo tienen máquinas de hardware simulado que actúan como sandbox, sino que cada sandbox también ejecuta un sistema operativo invitado completo para que las aplicaciones lo utilicen a voluntad.
Consistencia del contenedor:
debido a que los entornos de servidor local y de nube son diferentes, el proceso de empaquetado de aplicaciones siempre ha sido el paso más "doloroso" al utilizar PaaS.
Pero con la imagen del contenedor (es decir, rootfs), este problema se resolvió.
Dado que lo que está empaquetado en rootfs no es solo la aplicación, sino los archivos y directorios de todo el sistema operativo, significa que la aplicación y todas las dependencias que necesita para ejecutarse están empaquetadas juntas.
Para la mayoría de los desarrolladores, su comprensión de las dependencias de las aplicaciones siempre se ha limitado al nivel del lenguaje de programación. Por ejemplo, Godeps.json de Golang. Pero, de hecho, un hecho que siempre se ha pasado por alto con facilidad es que para una aplicación, el sistema operativo en sí es la "biblioteca de dependencias" más completa que necesita para ejecutar.
Con la capacidad de las imágenes de contenedor para "empaquetar el sistema operativo", este entorno dependiente más básico finalmente se ha convertido en parte del entorno limitado de la aplicación. Esto le da al contenedor la así llamada consistencia: ya sea en el local, la nube o en una máquina en cualquier lugar, el usuario solo necesita descomprimir la imagen del contenedor empaquetado, luego se reconstruirá el entorno de ejecución completo requerido para el funcionamiento de esta aplicación. Salió.
Esta coherencia del entorno operativo hasta el nivel del sistema operativo cierra la brecha insuperable entre el desarrollo de aplicaciones y los entornos de ejecución remota.
Union File System: Union File System también se llama UnionFS.
Docker no siguió el proceso estándar anterior de hacer rootfs al implementar imágenes de Docker, e hizo una innovación:
Docker introdujo el concepto de capas en el diseño de imágenes. En otras palabras, cada paso de la operación de duplicación del usuario generará una capa, que es un rootfs incremental. Se utiliza una capacidad denominada Union File System.
La función principal es montar varios directorios en diferentes ubicaciones (montaje de unión) en el mismo directorio.
Por ejemplo, ahora hay dos directorios A y B, que tienen dos archivos respectivamente:

[root@xingdian ~]# tree
        ├── A
        │  ├── a
        │  └── x
        └── B
          ├── b
          └── x

Luego, use el método de montaje conjunto para montar estos dos directorios en un directorio común C:

[root@xingdian ~]# mkdir C
[root@xingdian ~]# yum install funionfs -y   //我这里用的是centos7自带的联合文件系统,效果一样
[root@xingdian ~]# funionfs  -o dirs=./A:./B none ./C

Verifique el contenido del directorio C nuevamente, y podrá ver que los archivos de los directorios A y B están fusionados:

[root@xingdian ~]# tree ./C
        ./C
        ├── a
        ├── b
        └── x

Como puede ver, en el directorio combinado C, hay tres archivos a, byx, y solo hay un archivo x. Este es el significado de "fusionarse".
Además, si realiza cambios en los archivos a, byx en el directorio C, estos cambios también tendrán efecto en los directorios A y B.

[root@xingdian ~]# echo hello >> C/a
[root@xingdian ~]# cat C/a
hello
[root@xingdian ~]# cat A/a
hello
[root@xingdian ~]# echo hello1 >> A/a
[root@xingdian ~]# cat A/a
hello
hello1
[root@xingdian ~]# cat C/a
hello
hello1

Archivo Dockerfile de nivel empresarial para crear un contenedor

1. Archivo Dockerfile para compilar nginx

[root@xingdian ~]# cat Dockerfile 
FROM centos:7.2.1511
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
RUN yum -y install gcc openssl openssl-devel  pcre-devel zlib-devel make
ADD nginx-1.14.0.tar.gz /opt/
WORKDIR /opt/nginx-1.14.0
RUN ./configure --prefix=/opt/nginx 
RUN make && make install
WORKDIR /opt/nginx
RUN rm -rf /opt/nginx-1.14.0
ENV NGINX_HOME=/opt/nginx
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nginx/sbin
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
注意:
Nginx的docker仓库原文说明如下:
If you add a custom CMD in the Dockerfile, be sure to include -g daemon off; in the CMD in order fornginx to stay in the foreground, so that Docker can track the process properly (otherwise your container will stop immediately after starting)!
Running nginx in debug mode
Images since version 1.9.8 come with nginx-debug binary that produces verbose output when using higher log levels. It can be used with simple CMD substitution: 
$ docker run --name my-nginx -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx nginx -g 'daemon off;'
Similar configuration in docker-compose.yml may look like this:

web:
  image: nginx
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
  command: [nginx, '-g', 'daemon off;']

2. Archivo Dockerfile para compilar redis

FROM centos:7.2.1511
MAINTAINER zhaokun redis4 jichujingxiang
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
RUN yum -y install gcc make
ADD redis-4.0.9.tar.gz /opt/
RUN cd /opt/ && mv redis-4.0.9  redis  && cd /opt/redis && make && make install
RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/
EXPOSE 6379
CMD ["redis-server","/opt/redis/conf/redis.conf"]
基于哨兵模式的redis镜像
FROM centos:7.2.1511
MAINTAINER  redis4 jichujingxiang
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
RUN yum -y install gcc make
ADD redis-4.0.9.tar.gz /opt/
ADD run.sh /
RUN cd /opt/ && mv redis-4.0.9  redis  && cd /opt/redis && make && make install
RUN mkdir -p /opt/redis/logs && mkdir -p /opt/redis/data && mkdir -p /opt/redis/conf && cp /opt/redis/redis.conf /opt/redis/conf/ && cp /opt/redis/src/redis-trib.rb /usr/local/bin/ && cp /opt/redis/sentinel.conf /opt/redis/conf/ && chmod 777 /run.sh
EXPOSE 6379
CMD ["./run.sh"]
#cat /run.sh
#!/usr/bin/bash
#2018/10/24
#行癫
cd /opt/redis/src/
./redis-server /opt/redis/conf/redis.conf &                    #这一个要放在后台运行,不然下面的启动不了
./redis-sentinel /opt/redis/conf/sentinel.conf

3. Archivo Dockerfile para compilar jenkins

FROM local/c7-systemd
ADD jdk-9.0.1_linux-x64_bin.tar.gz /usr/local/
ADD apache-tomcat-9.0.14.tar.gz /usr/local/
WORKDIR /usr/local/
ENV JAVA_HOME=/usr/local/java
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CATALINA_HOME=/usr/local/tomcat
ENV export JAVA_HOME CATALINA PATH
RUN mv jdk-9.0.1 java && mv apache-tomcat-9.0.14 tomcat
COPY jenkins.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh run"]

Supongo que te gusta

Origin blog.csdn.net/kakaops_qing/article/details/109136914
Recomendado
Clasificación