В современных условиях Я, как и другие, зачастую работаю с разнородной инфраструктурой, включающей:

  • ноутбуки;

  • смартфоны и планшеты;

  • физические серверы;

  • виртуальные серверы;

  • контейнерные среды.

Возникает закономерный вопрос: какая операционная система и среда разработки обеспечат максимальную продуктивность при работе с таким парком оборудования?

На основании многолетнего опыта эксплуатации различных платформ сделан вывод, что Windows остаётся наиболее функциональной базовой операционной системой для повседневного использования. Но в статье хочу как раз рассказать, что неважно какая ОС на хосте.

Поскольку большинство современных проектов развёртывается в Docker, оптимальная среда разработки должна обеспечивать:

  • совместимость с Linux‑окружением;

  • интеграцию с инструментами контейнеризации;

  • удобство отладки и тестирования.

Практическая реализация

Этап 1. Виртуальная машина Ubuntu

Первым шагом стала организация виртуальной машины с Ubuntu на ноутбуке: попробовал Hyper‑V, VMWare и VirtualBox, пробовал IDE запускать внутри ВМ, но потом перешел на подключение по SSH, а IDE запускать на хосте (в этом плане лучше всего подходит Hyper‑V).

Преимущества подхода:

  • изоляция среды разработки от основной ОС;

  • возможность быстрого клонирования/восстановления;

  • тестирование в «чистом» Linux‑окружении.

Этап 2. Контейнерная среда с удалённым доступом

Для повышения эффективности был реализован переход на контейнерную модель:

1. Создание Docker‑контейнера с предустановленным окружением:

Dockerfile
FROM ubuntu:24.04
RUN apt-get update
RUN apt-get install \
            pip \
            openssh-server \
            git \
            sshpass  \
            python3.13-full -y && rm -rf /var/cache/apt
# Настройка SSH‑доступа:
RUN userdel -r ubuntu
RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1000 dev
RUN echo 'dev:dev' | chpasswd
RUN service ssh start
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"] 

2.   Запуск на сервере:

Запущен контейнер был на железном сервере с внешним IP и я мог подключаться к нему из любой точки мира. Минимальные настройки безопасности, конечно же были, но как известно, после перезапуска или редеплоя файловая система контейнера бы обнулялась. Задача была решена монтированием соответствующих папок и файлов через файл:

docker-compose.yml
services:
   mi113r:
      image: "registry.gitlab.com/devops1505017/vscode-python/dev_platform:1.2"
      tty: true
      logging:
         driver: "json-file"
         options:
            max-size: "200k"
            max-file: "10"
      restart: always 
      ports:
         - "ХХХ:22"
      volumes:
         - /home/dev/projects:/home/ubuntu/projects
         - /home/dev/conf/ssh_config.conf:/etc/ssh/sshd_config.d/ххх.conf
         - /home/dev/conf/.ssh/:/home/ubuntu/.ssh/
         - /home/dev/conf/.gitconfig:/home/ubuntu/.gitconfig

Самые важные здесь – это настройки безопасности:
- /home/dev/conf/ssh_config.conf:/etc/ssh/sshd_config.d/ssa.conf
- /home/dev/conf/.ssh/:/home/ubuntu/.ssh/

Но это уже совсем другая история

3. Интеграция с VS Code:

  • установка ��асширения Remote‑SSH;

  • добавление хоста в конфигурацию;

Этап 3. Docker-CLI внутрь контейнера для разработки

Для подключения по SSH и разработки этого было достаточно, но потом мне захотелось собирать контейнеры и выполнять команды docker (с использование docker context) прямо из среды разработки без переключений и я интегрировал docker-cli внутрь docker контейнера (да получился докер в докере, но это работает)

расширенный Dockerfile:
FROM ubuntu:24.04
RUN apt-get update
RUN apt-get install \
            nano \
            wget \
            pip \
            openssh-server \
            git \
            sudo \
            make \
            sshpass \
            apt-transport-https \
            ca-certificates \
            curl \
            gnupg \
            lsb-release \
            software-properties-common \
            python3.13-full \
            gcc -y \
            && add-apt-repository -y ppa:deadsnakes/ppa \
            && rm  -rf /var/cache/apt
RUN wget -O- https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor | sudo tee /etc/apt/keyrings/docker.gpg > /dev/null
RUN echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable"| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN sudo apt update
RUN sudo apt-get install docker-ce docker-ce-cli containerd.io -y && rm -rf /var/cache/apt

RUN userdel -r ubuntu
RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1000 dev
RUN echo 'dev:dev' | chpasswd
RUN service ssh start
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]

Также необходимо будет добавить папки монтирования в docker-compose.yml, чтобы обеспечить сохранение настроек при перезапуске:

- /home/dev/conf/.docker/:/home/ubuntu/.docker/
- /home/dev/conf/etc/docker/:/etc/docker/

Этап 4. Code Anywhere

В короткие поездки я могу не взять с собой ноутбук, только планшет и вот тут самое интересное … я перепробовал уйму IDE, даже писал кусочки кода в vim подключившись по ssh, но это очень не удобно.

Ознакомившись со статьями:
            - Пишите код везде. Настройте сервер кода с помощью VS Code Server
            - Установка Visual Studio Code в облаке

Я решил проверить на практике, как это работает на самом деле … установить VSCode-server оказалось невероятно просто:

curl -fsSL https://code-server.dev/install.sh | sh

А вот запустить  VSCode-server стандартным способом через systemctl внутри докера не получится, но оно нам и не нужно, можем запустить с выводом в консоль, главное объявить  команду на этапе сборки image:

CMD ["/usr/bin/code-server", "--bind-addr", "0.0.0.0:8080", "--auth", "password"]

такой подход заблокировал запуск SSH, разрешить конкуренцию сервисов удалось с помощью скрипта на bash: запуск одновременно двух процессов (скрипт для Dockerfile):

RUN echo '#!/bin/bash' > /start.sh && \
    echo '/usr/sbin/sshd -D &' >> /start.sh && \
    echo 'P1=$!' >> /start.sh && \
    echo '/usr/bin/code-server --bind-addr 0.0.0.0:8080 --auth password &' >> /start.sh && \
    echo 'P2=$!' >> /start.sh && \
    echo 'wait $P1' >> /start.sh && \
    echo 'wait $P2' >> /start.sh && \
    chmod +x /start.sh
EXPOSE 22 8080
ENTRYPOINT ["/start.sh"]

Теперь CodeAnyWhere зазвучал по новому, полноценно.

Этап 5. Доменное имя

 С HTTP в nginx проблем не должно возникнуть:

server {
            listen 80;
            listen [::]:80;
            server_name youdomain.oonline;
            server_tokens off; 
            location /.well-known/acme-challenge/ {
                        root /var/www/certbot/;
                        }
            location / {
                        return 301 https://youdomain.oonline$request_uri; 
            }
}

но эта конструкция мне нужна только чтобы получить сертификат Lets Encrypt. А вот с HTTPS пришлось повозиться … после запуска появлялась ошибка

решается эта ошибка четырьмя строчками в “location /” :

proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
nginx.conf (конструкция целиком)
server {
   listen 443 ssl;
   listen [::]:443 ssl;
   server_name youdomain.oonline; 
   ssl_certificate /etc/letsencrypt/live/youdomain.oonline/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/youdomain.oonline/privkey.pem;
   
   ssl_protocols TLSv1.2 TLSv1.3;
   ssl_ciphers HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers on;
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 24h;
   
   location / {
      proxy_pass http://vscode-server:8080;
      proxy_set_header Host $host;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection upgrade;
      proxy_set_header Accept-Encoding gzip;
   
      client_max_body_size 0;
   }
}

Что в итоге:

  1. Контейнер с Ubuntu, к которому можно подключится по SSH.

  2. При подключении к контейнеру мы можем использовать docker CLI и собирать другие контейнеры.

  3. У этого «комбайна» для разработки есть WEB‑интерфейс с полноценным VSCode, в котором есть отладка и доступ к терминалу.

  4. Есть полноценный IDE, который запускается на планшете (будь то iOS или Android)

ссылка на git

Комментарии (1)


  1. pavelmvl
    05.11.2025 05:50

    Из статьи не понятно для чего нужен ssh сервер внутри контейнера, codeserver выполняет такие же функции, и при этом вам не нужно запускать 2 сервиса в контейнере.

    Если нет каких-либо требований по реверс прокси, то я советовал бы посмотреть в сторону caddy вместо nginx. Он умеет сам, без certboot обновлять letsencrypt сертификаты.

    Есть вопросы и к Dockerfile. Он сильно не оптимальный. Если интересно, то можно разобрать отдельно.