创建C++ docker开发环境(VScode)

Tuesday, March 7, 2023
本文共1599字
4分钟阅读时长

⚠️本文是作者P3troL1er原创,首发于https://peterliuzhi.top/posts/%E5%88%9B%E5%BB%BAc++-docker%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83vscode/。商业转载请联系作者获得授权,非商业转载请注明出处!

The world makes way for the man who knows where he is going. — Ralph Waldo Emerson

引子

因为虚拟机太慢太大,我尝试了一下WSL。但是不知道为什么,在我的机器上WSL卡成了PPT,无奈放弃,最终选择了docker。不得不说,空间占用又小,速度又快!

Dockerfile

这个环境基于ubuntu:22.04,安装了gcc、clang、clang-format、cmake等基本工具,同时安装了boost等基本的库(不够自己再装),同时安装了python,源都换成了阿里源

本Dockerfile魔改自利用Docker搭载C/C++开发环境 - 知乎

FROM ubuntu:22.04
LABEL maintainer="peterliuall <peterliuforever@gmail.com>"

ENV DEBIAN_FRONTEND noninteractive

ENV TZ Asia/Shanghai

# 添加源
COPY ./sources.list /etc/apt/

RUN dpkg --add-architecture i386 && \
    apt-get upgrade && \
    apt-get update && \
    apt-get install -y build-essential \
    locales \
    libc6:i386 \
    libc6-dbg:i386 \
    libc6-dbg \
    lib32stdc++6 \
    g++-multilib \
    gdb \
    gdb-multiarch \
    netcat \
    socat \
    git \
    patchelf \
    gawk \
    file \
    python3-distutils \
    bison \
    rpm2cpio cpio \
    zstd \
    binutils \
    qemu \
    strace \
    ltrace \
    nasm \
    wget \
    cmake \
    clang-tidy \
    clangd \
    net-tools \
    iputils-ping \
    openssh-server \
    rsync \
    gcc g++ \
    tmux \
    binutils-dev \
    mpi-default-dev libicu-dev libbz2-dev libssl-dev libffi-dev libboost-all-dev \
    python3-dev python3-pip \
    sudo \
    curl \
    ssh \
    vim \
    re2c \
    clang clang-format global cppcheck \
    tzdata --fix-missing

RUN python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -U pip &&\
    python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
    python3 -m pip install lizard 

RUN git clone https://github.com/ninja-build/ninja.git && \
    cd ninja && \
    ./configure.py --bootstrap && \
    cp ninja /usr/bin/ && \
    apt-get install -y ninja-build && ninja --version

RUN ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata && \
    ln -snf `which python3` /usr/local/bin/python

RUN mkdir /var/run/sshd && mkdir ~/.ssh
# RUN sed -ri 's/^PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config

RUN sed -ri 's/RSYNC_ENABLE=false/RSYNC_ENABLE=true/g' /etc/default/rsync
COPY rsync.conf /etc

RUN echo 'root:123456' |chpasswd

RUN mkdir /root/sync

RUN ls /usr/bin/ && \
    python3 -V && \
    locale-gen en_US.UTF-8  && \
    echo 'LANG="en_US.UTF-8"\nLANGUAGE="en_US.UTF-8:"' >  /etc/default/locale && \
    echo 'export LANG="en_US.UTF-8"\nexport LANGUAGE="en_US.UTF-8:"' >  /etc/bash.bashrc && \
    /bin/bash -c "source /etc/bash.bashrc"

WORKDIR /cpp/

COPY entrypoint.sh /sbin
RUN chmod +x /sbin/entrypoint.sh
ENTRYPOINT [ "/sbin/entrypoint.sh" ]

其他文件

其他文件包括entrypoint.sh、rsync.conf、sources.list,全都放在与Dockerfile同一目录下:

entrypoint.sh

#!/bin/bash

/usr/bin/rsync --daemon --config=/etc/rsync.conf
/usr/sbin/sshd -D

rsync.conf

# 编辑配置信息
max connections = 8
log file = /var/log/rsync.log
timeout = 300

[sync] # 模块名
comment = sync
# path为需要同步的文件夹路径
path = /root/sync
read only = no
list = yes
uid = root
gid = root

sources.list

这个文件用来放Ubuntu22.04的阿里源/etc/apt/sources.list:

deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse

docker-compose.yml

这个文件用于生成容器,其中操作包括共享文件夹、暴露端口,记得改volumes下的//d/database_BooksAndFiles/CPP/为你自己主机上的文件夹

version: "2.2"

services:
  ubuntu:
    image: ubuntu:latest
    container_name: ubuntu
    working_dir: /cpp/
    volumes:
      - //d/database_BooksAndFiles/CPP/:/cpp/
    ports:
      - "22:22" # 22是ssh端口
      - "873:873" # 873是srync端口
    cap_add:
      - ALL
    tty: true

如何食用

首先先build镜像文件:

docker build -t ubuntu:latest . 

然后生成容器:

docker-compose up -d

如果想要登录docker的shell,可以使用如下命令:

docker exec -it <镜像文件id或全名> /bin/bash

下一次重启容器,可以使用docker desktop,也可以使用命令行:

docker restart <镜像文件id或全名>

然后在Windows Terminal中试一试ssh root@127.0.0.1 -p 22看一下能不能连上,能连上就可以用vscode连上

如果不能连上,可以参见这篇SSH连接报错:Permission denied, please try again.的解决方法 - 腾讯云开发者社区-腾讯云

使用vscode连接

先保证你的vscode有安装以下插件:

文内图片

然后在这里打开一个config文件:

文内图片

然后更改config文件如下:

文内图片

其中C++Docker可以改成你喜欢的名字

然后就可以连接啦

通过密钥免密连接

因为vscode每次连接、更换文件夹都要输入密码,非常的不方便,因此我们可以使用公私密钥实现免密登录

首先我们在Windows上生成公私密钥(如果之前生成过了就不用重新生成了)(现在一般Windows都会自带openssh了,直接就能用):

ssh-keygen -t rsa

让它使用rsa加密的方式生成一个密钥,一直回车即可

然后进入C:\User\<你的用户名>\.ssh\文件夹,然后就能看到自己生成的id_rsa和id_rsa.pub,其中.pub文件就是公钥

然后使用scp将这个公钥传输到docker中的$HOME/.ssh/中,如果docker中没有这个文件夹,需要手动在docker中mkdir .ssh创建文件夹

scp id_rsa.pub root@127.0.0.1:/root/.ssh

然后登录你的docker中的shell,将这个公钥加入已认证密钥列表中:

cd ~/.ssh/
cat id_rsa.pub >> authorized_keys

然后就OK啦~