这篇文章上次修改于 320 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

1 docker 镜像制作示例

本章以将 rustdesk-server-demo 制作为 docker 为例,讲述 docker 镜像制作过程。

1.1 编译得到可执行的二进制文件

安装好 rust 语言后,编译 rustdesk-server-demo:

cd ~/github/rustdesk-server-demo
mkdir -p target/releae
cargo build --release

得到可直接执行的二进制文件路径为 ./target/release/rustdesk-server

可以验证可执行文件是否正确:

IP=127.0.0.1 ./target/release/rustdesk-server

1.2 编写 Dockerfile

server.Dockerfile:

FROM ubuntu:bionic
LABEL maintainer="jingpingyin@xxx.com"

WORKDIR /root
RUN apt update -y && \
    apt install -y --no-install-recommends \
    curl wget nasm yasm unzip zip sudo jq vim less

COPY ./target/release/rustdesk-server /root
COPY ./entrypoint.sh /root

RUN sudo chmod 777 entrypoint.sh
CMD bash /root/entrypoint.sh
  • FROM --- 基础镜像,本例在 Unbutu 镜像的基础上制作本镜像。
  • WORKDIR --- 设置镜像内的工作目录,本例中为 /root。
  • RUN --- 在 docker 内执行命令,多个 RUN 命令合并成一个,可以减小镜像大小。本例先后利用该命令安装了一些工具和修改脚本权限。
  • COPY --- 将主机上的目录或文件拷贝到 docker 镜像内,本例中:

    • 将编译生成的可执行二进制文件 ./target/release/rustdesk-server 拷贝到 docker 镜像中的 /root 目录下
    • 将 docker 启动后要执行的脚本文件 ./entrypoint.sh 拷贝到 docker 镜像中的 /root 目录下
  • CMD --- 执行容器启动命令。

容器启动后要执行的脚本 entrypoint.sh:

#!/bin/bash -e

mkdir -p /root/logs
/root/rustdesk-server >> "/root/logs/server_$(date +%Y%m%d-%H%M).log" 2>&1

执行二进制文件 rustdsk-server,并将其 log 重定向到容器中的 /root/logs 目录下。

1.3 docker 镜像

制作 docker 镜像:

docker build -t 镜像仓库/xremote-server:demo -f server.Dockerfile .
  • -t --- 为镜像指定名称:标签,本例镜像名称为 镜像仓库/xremote-server,标签为 demo
  • -f --- 指定 Dockerfile,本例为 server.Dockerfile

上传 docker 镜像到指定仓库:

docker push 镜像仓库/xremote-server:demo

以上两条命令中可以不指定镜像仓库,会默认上传到官方的仓库中。

1.4 运行 docker 容器

执行 docker run:

IMAGE_FULL_TAG=镜像仓库/xremote-server:demo
CONTAINER_NAME="rustdesk-server-demo"
HOST_SIGNALING_PROT=21116
HOST_RELAY_PROT=21117
CONTAINER_SIGNALING_PORT=21116
CONTAINER_RELAY_PORT21117
IP=127.0.0.1

docker run -itd --restart=always --net bridge \
          --name "${CONTAINER_NAME}" \
          -p "${HOST_SIGNALING_PROT}:${CONTAINER_SIGNALING_PORT}/udp" \
          -p "${HOST_SIGNALING_PROT}:${CONTAINER_SIGNALING_PORT}" \
          -p "${HOST_RELAY_PROT}:${CONTAINER_RELAY_PORT}" \
          -e IP="${IP}" \
          -v "${ROOT_DIR}/logs/${CONTAINER_NAME}/:/root/logs" \
          ${IMAGE_FULL_TAG}
  • -i, --interactive,保持 STDIN 打开
  • -t, --tty,分配一个伪 TTY
  • -d, --detach,在后台运行,并打印容器 ID
  • --restart,容器重启策略,本例为无限重启
  • --net,容器的网络设置,本例为桥接模式,只有指定桥接模式才能进行端口映射
  • --name,容器的名称
  • -p, --publish,端口映射,主机端口:容器端口。注意,对于 udp 端口,要加 /udp
  • -e, --env,设置容器内的环境变量,本例设置了 IP=127.0.0.1
  • -v, --volume,挂载,主机目录:容器目录

运行的 docker run 后会自动执行 docker pull 来下载镜像。

2 使用 docker 作为开发环境

  • 制作 docker

    docker build . -t xremote
  • 在 docker 内运行指令:

    以 xremote 身份进入 docker:

    docker exec -it -u xremote "$XREMOTE_CONTAINER_NAME"

    不进入 docker 时,以 xremote 身份在 docker 内部执行命令:

    docker exec -i -u xremote "$XREMOTE_CONTAINER_NAME" \
            bash -c "source /home/xremote/.cargo/env && cd client && bash release_build.sh build_deb"
  • 查看 docker 状态:

    docker ps
  • 查看日志

    docker logs --follow orbit-setup-script-nitro-1  
  • 即使 docker 停了,也可以进去查看情况

    docker run -it --entrypoint=sh nitro-node-gasless:latest

3 docker compose

使用 docker-compose 的好处之一:避免每次启动 docker 时写一堆启动参数。

docker-compose.yml 示例:

version: "3.4"
# reboot: docker-compose up -d [service]
services:
  xremote-server:
    image: "image_name:label"
    container_name: "container_name"
    network_mode: "host"
    environment:
      - ENV=production
    volumes:
      - "${HOME}/app/log:/opt/app/log"
      - "${HOME}/app/config:/opt/app/config"
    restart: always
    command: bash -c "/opt/app/run.sh"

拉取 docker 镜像:

docker-compose pull

启动 docker:

docker-compose up -d

停止:

docker-compose down

查看日志:

docker-compose logs -f xremote

或者直接查看 ${HOME}/app/log