Debian镜像(tini进程管理器)¶
Debian官方仓库已经提供了 Docker tini进程管理器 ,这意味着无需单独复制 tini
(类似 Fedora镜像(采用tini替代systemd) 就不得不从容器外部复制对应的 tini
到镜像中)
dockerhub: debian 提供官方镜像(需要梯子):
当前 debian.org 最新版本是
bookworm
(12.6),通过tag
关键字bookworm
或latest
引用
tini运行ssh debian-ssh-tini
¶
参考之前 Ubuntu镜像(采用tini替代systemd) 经验,构建Dockerfile
FROM debian:latest
ENV container=docker
RUN apt update -y
RUN apt upgrade -y
# Debian仓库内置tini,可以直接安装
RUN apt install tini
# Copy tini entrypoint script
COPY entrypoint_ssh_cron_bash /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Fedora docker image not include systemd,install systemd by initscripts
RUN apt -y install sudo passwd openssh-client openssh-server curl
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# add account "admin" and give sudo privilege
RUN groupadd -g 505 admin
RUN useradd -g 505 -u 505 -d /home/admin admin
RUN adduser admin sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# set TIMEZONE to Shanghai
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir /run/sshd
RUN ssh-keygen -A
# run service when container started - sshd
EXPOSE 22:1122
# Run your program under Tini
# CMD ["/your/program", "-and", "-its", "arguments"]
CMD ["/entrypoint.sh"]
构建镜像:
docker build --rm -t debian-ssh-tini .
这里我遇到一个报错:
[+] Building 32.9s (2/2) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 1.04kB 0.0s
=> ERROR [internal] load metadata for docker.io/library/debian:latest 32.8s
------
> [internal] load metadata for docker.io/library/debian:latest:
------
Dockerfile:1
--------------------
1 | >>> FROM debian:latest
2 | MAINTAINER vincent huatai <vincent@huatai.me>
3 |
--------------------
error: failed to solve: DeadlineExceeded: DeadlineExceeded: DeadlineExceeded: debian:latest: failed to copy: httpReadSeeker: failed open: failed to do request: Get "https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/19/19fa7f391c55906b0bbe77bd45a4e7951c67ed70f8054e5987749785450c0442/data?verify=1723911692-vjk1SJX8qBVoT%2FQRQSQuHdu%2BCsQ%3D": dial tcp 31.13.87.34:443: i/o timeout
FATA[0033] no image was built
FATA[0033] exit status 1
通过 Colima代理 来解决无法访问问题
运行容器: 注意这里继承了 Colima存储管理 中两个HOST物理主机卷映射到容器内部,以便提供SSH密钥以及工作
docs
目录
docker run -dt --name debian-ssh-tini --hostname debian-ssh-tini \
-p 1122:22 \
-v /Users/huatai/secrets:/home/admin/.ssh \
-v /Users/huatai/docs:/home/admin/docs \
debian-ssh-tini:latest
一切顺利,现在在HOST主机上配置
~/.ssh/config
添加访问debian容器的SSH登陆(端口1122):
Host debian
HostName 127.0.0.1
User admin
Port 1122
备注
HOST主机的 ~/secrets
包含了SSH公钥,所以如果被正确挂载到容器的 ~/.ssh
目录,就能够无需密码登陆容器
现在 ssh debian
就能够登陆到运行的容器中,并且执行 df -h
可以看到如下输出,显示HOST主机的存储卷被正确挂载到容器内部(包括登陆密钥):
Filesystem Size Used Avail Use% Mounted on
overlay 58G 1.8G 56G 4% /
tmpfs 64M 0 64M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/root 58G 1.8G 56G 4% /etc/hosts
mount1 234G 149G 86G 64% /home/admin/.ssh
mount2 234G 149G 86G 64% /home/admin/docs
tmpfs 3.9G 0 3.9G 0% /proc/acpi
tmpfs 3.9G 0 3.9G 0% /proc/scsi
tmpfs 3.9G 0 3.9G 0% /sys/firmware
开发环境 debian-dev
¶
在 debian-ssh-tini
基础上,增加开发工具包安装:
debian-dev
包含了安装常用工具和开发环境:
FROM debian:latest
ENV container=docker
# 容器内代理设置: 物理服务器上通过SSH Tunnel访问墙外HTTP/HTTPS代理,所以IP地址是Docker的NAT网络网关IP
# 如不需要请注释掉
# 不过我觉得比较灵活的方式还是配置Docker客户端 ~/.docker/config.json
#ENV HTTP_PROXY "http://172.17.0.1:3128"
#ENV HTTP_PROXY "http://172.17.0.1:3128"
#ENV FTP_PROXY "ftp://172.17.0.1:3128"
#ENV NO_PROXY "*.baidu.com,192.168.0.0/16,10.0.0.0/8"
RUN apt clean
RUN apt update -y
RUN apt upgrade -y
# Debian仓库内置tini,可以直接安装
RUN apt -y install tini
# Copy tini entrypoint script
COPY entrypoint_ssh_cron_bash /entrypoint.sh
RUN chmod +x /entrypoint.sh
# SSH
RUN apt -y install sudo passwd openssh-client openssh-server curl
# Utilities
RUN apt -y install cron tmux vim-tiny locales net-tools iproute2 dnsutils plocate gnupg2 git tree unzip lsof wget
# 补全locales
RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
RUN echo "LANG=en_US.UTF-8" > /etc/locale.conf
RUN locale-gen en_US.UTF-8
# c program
RUN apt -y install glibc-doc manpages-dev libc6-dev gcc build-essential
# 编译neovim需要
RUN apt -y install cmake gettext
# ruby program install rvm
# python program (debian already inatalled python3)
RUN apt -y install python3.11-venv
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# add account "admin" and give sudo privilege
RUN groupadd -g 505 admin
RUN useradd -g 505 -u 505 -s /bin/bash -d /home/admin -m admin
RUN adduser admin sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# set TIMEZONE to Shanghai
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir /run/sshd
RUN ssh-keygen -A
USER admin
# ruby program: rvm install ruby in $HOME
RUN gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
RUN curl -sSL https://get.rvm.io | bash -s stable
# /bin/sh 不支持source,需要使用 .
# 每个RUN都是一个容器,所以为了继承环境变量来运行多个命令,将这些命令写成一行RUN
# rvm需要使用BASH,所以最终改成 bash -c 'xxx && yyy && zzz'
RUN bash -c 'source /home/admin/.rvm/scripts/rvm && rvm install 3.3.4 && gem install rails'
# 我使用Jekyll构建个人blog,如不需要请注释掉下面一行
RUN bash -c 'source /home/admin/.bashrc && gem install bundler jekyll'
# 如果报错 "gem: command not found" (我在debian的ARM镜像时遇到),则改成 "source /home/admin/.rvm/scripts/rvm"
# RUN bash -c 'source /home/admin/.rvm/scripts/rvm && gem install bundler jekyll'
# python program: virtualenv
RUN bash -c 'cd /home/admin && python3 -m venv venv3'
# 我使用Sphinx doc来撰写Cloud-Atlas文档,如不需要请注释掉下面两行
RUN bash -c 'source /home/admin/venv3/bin/activate && pip install sphinx && pip install sphinx_rtd_theme && pip install sphinxnotes-strike'
RUN bash -c 'source /home/admin/venv3/bin/activate && pip install sphinxcontrib-video && pip install sphinxcontrib-youtube'
# node program: nvm install node
RUN bash -c "cd /home/admin && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
RUN bash -c "source /home/admin/.bashrc && nvm install 22"
# 如果报错 "nvm: command not found" (在debian的ARM镜像时遇到),则改成 "source /home/admin/.nvm/nvm.sh" 来加载nvm (参考 ~/.bashrc )
# RUN bash -c "/home/admin/.nvm/nvm.sh && nvm install 22"
# neovim
# 由于容器镜像构建时需要使用HTTP代理,所以这里配置git通过代理clone,如果没有GFW干扰或者运行时没有遇到类似 "error: RPC failed; curl 18 Transferred a partial file" 报错,则不需要添加git代理配置
#RUN git config --global http.proxy http://172.17.0.1:3128
# 当git使用operations over HTTP时,实际使用的是curl library
RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
RUN bash -c 'cd /home/admin/src && git clone https://github.com/huataihuang/cloud-studio.git && cd /home/admin/src/cloud-studio/config && sh install.sh'
RUN rm -rf /home/admin/src
# entrypoint.sh 需要使用root身份执行
USER root
# run service when container started - sshd
EXPOSE 22:1122
# Sphinx
EXPOSE 8080:18080
# Jekyll
EXPOSE 4000:14000
# HTTP
EXPOSE 80:1180
# HTTPS
EXPOSE 443:1443
# Run your program under Tini
# CMD ["/your/program", "-and", "-its", "arguments"]
CMD ["/entrypoint.sh"]
构建
debian-dev
镜像:
docker build --rm -t debian-dev .
运行
debian-dev
:
docker run -dt --name debian-dev --hostname debian-dev \
-p 1122:22 \
-p 18080:8080 \
-p 14000:4000 \
-p 1180:80 \
-p 1443:443 \
-v /Users/huatai/secrets:/home/admin/.ssh \
-v /Users/huatai/docs:/home/admin/docs \
debian-dev:latest
# 如果需要在运行时注入环境变量,则添加类似如下参数(添加代理案例)
# -e HTTP_PROXY=http://172.17.0.1:3128 \
# -e HTTPS_PROXY=http://172.17.0.1:3128 \
# -e NO_PROXY=localhost,127.0.0.1,*.baidu.com,192.168.0.0/16,10.0.0.0/8 \
问题排查记录¶
apt安装找不到软件包¶
我在 amd64
(x86_64)平台构建 debian-dev
成功,但是当我将同样的Dockerfile在 树莓派Raspberry Pi OS(64位)安装Docker 却遇到无法安装 tini
报错:
...
=> CACHED [ 2/36] RUN apt update -y 0.0s
=> CACHED [ 3/36] RUN apt upgrade -y 0.0s
=> ERROR [ 4/36] RUN apt -y install tini 0.6s
------
> [ 4/36] RUN apt -y install tini:
0.363
0.363 WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
0.363
0.366 Reading package lists...
0.373 Building dependency tree...
0.374 Reading state information...
0.375 E: Unable to locate package tini
------
Dockerfile:17
--------------------
15 |
16 | # Debian仓库内置tini,可以直接安装
17 | >>> RUN apt -y install tini
18 |
19 | # Copy tini entrypoint script
--------------------
ERROR: failed to solve: process "/bin/sh -c apt -y install tini" did not complete successfully: exit code: 100
我最初以为是 Docker 代理快速起步 设置代理网关错误(我确实错误设置了 127.0.0.1:3128
,正确应该是 172.17.0.1:3128
),但是实践发现即使修正了代理网关IP也同样报错。最后我发现,原来ARM版本的debian官方镜像似乎有仓库配置残留,在Dockerfile中添加 apt clean
步骤清理现场,然后执行升级和安装就能够正常工作。(已修正上文 debian-dev
Dockerfile)
git下载出现curl报错"RPC failed; curl 18 Transferred a partial file"¶
我在 树莓派Raspberry Pi OS(64位)安装Docker 上执行构建(家里的网络远不如阿里云虚拟机公网),反复出现curl报错:
=> ERROR [35/37] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && export http_proxy 83.3s
------
> [35/37] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && export http_proxy && export https_proxy=\$http_proxy && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc':
0.340 Cloning into 'neovim'...
83.19 error: RPC failed; curl 18 Transferred a partial file
83.19 error: 1183 bytes of body are still expected
83.19 fetch-pack: unexpected disconnect while reading sideband packet
83.19 fatal: early EOF
83.19 fatal: fetch-pack: invalid index-pack output
------
Dockerfile:84
--------------------
82 |
83 | # neovim
84 | >>> RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && export http_proxy && export https_proxy=\$http_proxy && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
85 | RUN bash -c 'cd /home/admin/src && git clone https://github.com/huataihuang/cloud-studio.git && cd /home/admin/src/cloud-studio/config && sh install.sh'
86 | RUN rm -rf /home/admin/src
--------------------
ERROR: failed to solve: process "/bin/sh -c bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && export http_proxy && export https_proxy=\\$http_proxy && make CMAKE_EXTRA_FLAGS=\"-DCMAKE_INSTALL_PREFIX=$HOME/neovim\" && make install && echo \"export PATH=\\\"\\$HOME/neovim/bin:\\$PATH\\\"\" >> /home/admin/.bashrc && echo alias vi=\\\"\\$HOME/neovim/bin/nvim\\\" >> /home/admin/.bashrc'" did not complete successfully: exit code: 128
注意,这里报错的 error: 1183 bytes of body are still expected
每次可能数值不同,看起来就是传输错误
我尝试增加 git config --global http.proxy http://172.17.0.1:3128
这样可以确保 git 通过代理访问 HTTPS 来解决,但是我发现并没有解决上述报错。既然 git 在执行 operations over HTTP 实际使用的是curl库,所以我也尝试了 echo "proxy=172.17.0.1:3128" > /home/admin/.curlrc
来指定curl代理,但是此时报错:
=> [37/38] RUN echo "proxy=172.17.0.1:3128" > ~/.curlrc 0.5s
=> ERROR [38/38] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git' 82.7s
------
> [38/38] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git':
0.525 Cloning into 'neovim'...
82.65 error: RPC failed; curl 56 GnuTLS recv error (-9): Error decoding the received TLS packet.
82.65 error: 2389 bytes of body are still expected
82.65 fetch-pack: unexpected disconnect while reading sideband packet
82.65 fatal: early EOF
82.65 fatal: fetch-pack: invalid index-pack output
------
Dockerfile:89
--------------------
87 | # RUN git config --global http.proxy http://172.17.0.1:3128
88 | RUN echo "proxy=172.17.0.1:3128" > ~/.curlrc
89 | >>> RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git'
90 | #RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
91 | #RUN bash -c 'cd /home/admin/src && git clone https://github.com/huataihuang/cloud-studio.git && cd /home/admin/src/cloud-studio/config && sh install.sh'
--------------------
ERROR: failed to solve: process "/bin/sh -c bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git'" did not complete successfully: exit code: 128
参考 Github - unexpected disconnect while reading sideband packet 提示是网络不稳定导致的,可以尝试:
export GIT_TRACE_PACKET=1
export GIT_TRACE=1
export GIT_CURL_VERBOSE=1
不过输出信息其实和之前报错是一样的
git ssh最终解决方法¶
参考 Error Cloning Repository: RPC Failed; curl 18 transfer closed with outstanding read data remaining #18972 : 使用 ssh 替代 https 来进行 git clone ,可以解决网络传输问题。(应该可行,因为GFW没有屏蔽github的SSH)就是需要在Dockerfile中复制一个本地专用于git的SSH密钥,导致Dockerfile通用性较差。
不过,也不是很顺利,原因是每次访问github的HOST主机密钥变化,需要默认接受,否则会报错:
=> ERROR [39/39] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone git@github.com:neovim/neovim.git' 2.9s
------
> [39/39] RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone git@github.com:neovim/neovim.git':
0.915 Cloning into 'neovim'...
2.442 Host key verification failed.
2.442 fatal: Could not read from remote repository.
2.442
2.442 Please make sure you have the correct access rights
2.442 and the repository exists.
------
Dockerfile:94
--------------------
92 | # RUN echo "proxy=172.17.0.1:3128" > ~/.curlrc
93 |
94 | >>> RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone git@github.com:neovim/neovim.git'
95 |
96 | #RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
--------------------
ERROR: failed to solve: process "/bin/sh -c bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone git@github.com:neovim/neovim.git'" did not complete successfully: exit code: 128
参考 Git error: "Host Key Verification Failed" when connecting to remote repository 在执行git之前,首先添加github的主机密钥,避免脚本执行报错:
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
另外一个要点是,用户git的私钥不能有密码保护(我通常个人使用都会给RAS密钥对的私钥加上密码),否则也会报错: git@github.com: Permission denied (publickey).
,所以需要单独为git准备一个 没有密码保护 的RSA密钥对:
ssh-keygen -t rsa
ARM版本 neovim 安装clangd LSP¶
由于 LLVM clangd 没有在官方提供clangd的ARM64 for Linux,所以需要通过发行版安装 clangd
来实现 NeoVim clangd ARM版本 :
sudo apt install clangd-16
ln -s /usr/bin/clangd-16 ~/.local/share/nvim/mason/bin/clangd
mkdir ~/.local/share/nvim/mason/packages/clangd
开发环境 debian-dev
(ARM64版本)¶
备注
实践在 树莓派Raspberry Pi 5 的环境中进行,为 树莓派软件定义存储集群 做准备
结合上述要点,参考 git SSH操作脚本 方法改进Dockerfile(不过由于SSH方法比较复杂,常规还是采用 git operations over HTTP,只有为了解决网络阻塞GFW的时候才使用SSH方法),以下是完整Dockerfile:
FROM debian:latest
ENV container=docker
# 容器内代理设置: 物理服务器上通过SSH Tunnel访问墙外HTTP/HTTPS代理,所以IP地址是Docker的NAT网络网关IP
# 如不需要请注释掉
# 不过我觉得比较灵活的方式还是配置Docker客户端 ~/.docker/config.json
#ENV HTTP_PROXY "http://172.17.0.1:3128"
#ENV HTTP_PROXY "http://172.17.0.1:3128"
#ENV FTP_PROXY "ftp://172.17.0.1:3128"
#ENV NO_PROXY "*.baidu.com,192.168.0.0/16,10.0.0.0/8"
RUN apt clean
RUN apt update -y
RUN apt upgrade -y
# Debian仓库内置tini,可以直接安装
RUN apt -y install tini
# Copy tini entrypoint script
COPY entrypoint_ssh_cron_bash /entrypoint.sh
RUN chmod +x /entrypoint.sh
# SSH
RUN apt -y install sudo passwd openssh-client openssh-server curl
# Utilities
RUN apt -y install cron tmux vim-tiny locales net-tools iproute2 dnsutils plocate gnupg2 git tree unzip lsof wget
# 补全locales
RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment
RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
RUN echo "LANG=en_US.UTF-8" > /etc/locale.conf
RUN locale-gen en_US.UTF-8
# c program
RUN apt -y install glibc-doc manpages-dev libc6-dev gcc build-essential
# 编译neovim需要
RUN apt -y install cmake gettext
# ruby program install rvm
# python program (debian already inatalled python3)
RUN apt -y install python3.11-venv
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# add account "admin" and give sudo privilege
RUN groupadd -g 505 admin
RUN useradd -g 505 -u 505 -s /bin/bash -d /home/admin -m admin
RUN adduser admin sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# set TIMEZONE to Shanghai
RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir /run/sshd
RUN ssh-keygen -A
USER admin
# ruby program: rvm install ruby in $HOME
RUN gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
RUN curl -sSL https://get.rvm.io | bash -s stable
# /bin/sh 不支持source,需要使用 .
# 每个RUN都是一个容器,所以为了继承环境变量来运行多个命令,将这些命令写成一行RUN
# rvm需要使用BASH,所以最终改成 bash -c 'xxx && yyy && zzz'
RUN bash -c 'source /home/admin/.rvm/scripts/rvm && rvm install 3.3.4 && gem install rails'
# 我使用Jekyll构建个人blog,如不需要请注释掉下面一行
# RUN bash -c 'source /home/admin/.bashrc && gem install bundler jekyll'
# 如果报错 "gem: command not found" (我在debian的ARM镜像时遇到),则改成 "source /home/admin/.rvm/scripts/rvm"
RUN bash -c 'source /home/admin/.rvm/scripts/rvm && gem install bundler jekyll'
# python program: virtualenv
RUN bash -c 'cd /home/admin && python3 -m venv venv3'
# 我使用Sphinx doc来撰写Cloud-Atlas文档,如不需要请注释掉下面两行
RUN bash -c 'source /home/admin/venv3/bin/activate && pip install sphinx && pip install sphinx_rtd_theme && pip install sphinxnotes-strike'
RUN bash -c 'source /home/admin/venv3/bin/activate && pip install sphinxcontrib-video && pip install sphinxcontrib-youtube'
# node program: nvm install node
RUN bash -c "cd /home/admin && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
# RUN bash -c "source /home/admin/.bashrc && nvm install 22"
# 如果报错 "nvm: command not found" (在debian的ARM镜像时遇到),则改成 "source /home/admin/.nvm/nvm.sh" 来加载nvm (参考 ~/.bashrc )
RUN bash -c "source /home/admin/.nvm/nvm.sh && nvm install 22"
# neovim
# 这个步骤是为了解决GFW屏蔽,使用git clone的 over HTTP报错,不得已采用SSH模式,所以会复制密钥,如果直接通过git operations over HTTP工作正常,则不需要这个步骤
# 注意,需要在Dockerfile相同目录下执行 ssh-keygen -t rsa 生成密钥对(私钥不可密码保护),并将公钥上传到github以便能够git clone
USER admin
#### 接受github的主机认证密钥
#### 可以通过SSH忽略主机密钥 -o StrictHostKeyChecking=no 绕过
## -------------------------------------------------------------
## RUN mkdir /home/admin/.ssh
## RUN ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
## -------------------------------------------------------------
#### 采用git SSH方式
## -------------------------------------------------------------
RUN mkdir /home/admin/src
## COPY 命令复制的文件需要修改属主,否则ssh无法读取
COPY id_rsa /home/admin/src/id_rsa
USER root
RUN chown admin:admin /home/admin/src/id_rsa
USER admin
#### 指定git密钥,这里使用 --global 是因为当前没有在git项目目录下,不用这个参数会报错 "fatal: not in a git directory"
RUN git config --global core.sshCommand 'ssh -i /home/admin/src/id_rsa -o StrictHostKeyChecking=no'
#### git clone使用SSH方式是为了避免GFW干扰,使用git的operation over HTTP在代理模式下存在curl RPC报错
RUN bash -c 'source /home/admin/.bashrc && cd /home/admin/src && git clone git@github.com:neovim/neovim.git && cd /home/admin/src/neovim && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
RUN bash -c 'cd /home/admin/src && git clone git@github.com:huataihuang/cloud-studio.git && cd /home/admin/src/cloud-studio/config && sh install.sh'
RUN rm -rf /home/admin/src
RUN rm /home/admin/.gitconfig
#### ARM版本debian需要安装clangd以便完成Mason的clangd LSP支持
USER root
RUN apt -y install clangd-16
USER admin
RUN mkdir -p /home/admin/.local/share/nvim/mason/bin
RUN ln -s /usr/bin/clangd-16 /home/admin/.local/share/nvim/mason/bin/clangd
RUN mkdir /home/admin/.local/share/nvim/mason/packages/clangd
#### 使用git operations over HTTP较为简洁,但是会受到网络干扰影响出现 "error: RPC failed; curl 18 Transferred a partial file"
## -------------------------------------------------------------
# RUN bash -c 'mkdir /home/admin/src && source /home/admin/.bashrc && cd /home/admin/src && git clone https://github.com/neovim/neovim.git && cd /home/admin/src/neovim && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" && make install && echo "export PATH=\"\$HOME/neovim/bin:\$PATH\"" >> /home/admin/.bashrc && echo alias vi=\"\$HOME/neovim/bin/nvim\" >> /home/admin/.bashrc'
# RUN bash -c 'cd /home/admin/src && git clone https://github.com/huataihuang/cloud-studio.git && cd /home/admin/src/cloud-studio/config && sh install.sh'
# RUN rm -rf /home/admin/src
# entrypoint.sh 需要使用root身份执行
USER root
# run service when container started - sshd
EXPOSE 22:1122
# Sphinx
EXPOSE 8080:18080
# Jekyll
EXPOSE 4000:14000
# HTTP
EXPOSE 80:1180
# HTTPS
EXPOSE 443:1443
# Run your program under Tini
# CMD ["/your/program", "-and", "-its", "arguments"]
CMD ["/entrypoint.sh"]
构建
acloud-dev
镜像:
docker build --rm -t acloud-dev .
运行
acloud-dev
:
docker run -dt --name acloud-dev --hostname acloud-dev \
-p 1122:22 \
-p 18080:8080 \
-p 14000:4000 \
-p 1180:80 \
-p 1443:443 \
-v /home/admin/secrets:/home/admin/.ssh \
-v /home/admin/docs:/home/admin/docs \
acloud-dev
# 如果需要在运行时注入环境变量,则添加类似如下参数(添加代理案例)
# -e HTTP_PROXY=http://172.17.0.1:3128 \
# -e HTTPS_PROXY=http://172.17.0.1:3128 \
# -e NO_PROXY=localhost,127.0.0.1,*.baidu.com,192.168.0.0/16,10.0.0.0/8 \