将docker image编译为独立的便携式二进制文件

北月

前段时间发现一个非常极客的项目:dockerc,一直没时间去尝试,今天试了一下果然可以正常运行。

以下是我测试将 webman 镜像编译为二进制文件的项目目录。
可以不使用 opcache,我主要是为了测试把php代码先编译为 opcode,然后清空源文件。

webman
├── app
├── composer.json
├── composer.lock
├── config
├── Dockerfile
├── LICENSE
├── php
├── php.ini
├── process
├── public
├── README.md
├── runtime
├── start.php
├── support
├── vendor
├── windows.bat
└── windows.php

Dockerfile 内容:

FROM alpine:latest

RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories

RUN apk update && \
    apk --no-cache upgrade && \
    rm -rf /var/cache/apk/* && \
    mkdir -p /app/opcache

WORKDIR /app

COPY ./ /app/
# 直接使用 PHP 静态二进制文件
RUN mv /app/php /usr/local/bin/php && chmod +x /usr/local/bin/php
# 将 PHP 代码编译为 opcode
RUN find /app -type f -name "*.php" -exec php -c /app/php.ini -l {} \;
# 清空 PHP 源文件
RUN find /app -type f -name "*.php" -exec sh -c 'echo -n > {}' \;

EXPOSE 8787

CMD ["php", "-c", "php.ini", "start.php", "start"]

php.ini 内容:

date.timezone="UTC"
opcache.enable = 1
opcache.enable_cli = 1
opcache.save_comments = 0
opcache.file_update_protection = 0
opcache.validate_timestamps = 0
opcache.validate_permission = 0
opcache.validate_root = 0
opcache.file_cache = /app/opcache
opcache.file_cache_only = 1
opcache.file_cache_consistency_checks = 0
opcache.max_file_size = 0
opcache.file_update_protection = 0

步骤如下:

  1. 先构建 webman 镜像
    docker build . -t fuzqing/webman:8.3.6 --load
  2. 下载 dockerc
    wget https://github.com/NilsIrl/dockerc/releases/download/v0.2.1/dockerc
    chmod +x dockerc
  3. 使用 dockerc 将镜像导出为二进制文件
    ./dockerc --image docker-daemon:fuzqing/webman:8.3.6 --output webman.bin
  4. 然后就可以执行了
    ./webman.bin
  5. 验证
    可以将 webman.bin 上传到其它 x86_64 架构的 Linux 机器上测试,证明以下机器没有安装dockerphp,并且能成功运行。
    截图

注意:为了提高兼容性,需要先将 docker 配置为 vfs 存储驱动。
docker 文档地址:https://docs.docker.com/storage/storagedriver/vfs-driver/

207 1 0
1个评论

damao

好高级的玩法,可以用来做加密么?就是直接分发二进制文件,对方拿不到源码

  • 北月 14天前

    本质上来说还是会进行解压之后再运行的,可以获取到项目完整的 opcode,但是如果对方没有能力将 opcode 反编译为 PHP 源码,那么本方案也可以用来“加密”了,加解密的对抗无非是成本问题。
    另外,你完全可以不采用 PHP 二进制文件,我只是为了测试能否正常编译和执行,这就是一个 Docker Image,完全可以另外安装你喜欢的加密扩展,在 Dockerfile 里面对 PHP 源码进行混淆和加密处理,最后编译为 opcode 和清空源文件,而不影响本地的源代码。
    借助本思路,如果不喜欢使用 dockerc 导出为二进制文件,你也可以使用 Docker Image 进行交付,也就是说只少了 dockerc 导出步骤,部署时候采用 docker 的方式。

  • Tinywan 14天前

    为什么会有这个错误:mksquashfs: dl-call-libc-early-init.c:37: _dl_call_libc_early_init: Assertionsym != NULL' failed`

  • 北月 14天前

    哪个步骤出现的?导出阶段还是运行阶段?

  • 北月 14天前

    我使用的Debian和Ubuntu,导出阶段出问题估计是dockerc对某些系统不是很兼容

北月

3620
积分
0
获赞数
0
粉丝数
2021-12-01 加入
🔝