Coder IDE no Docker

Saudações.

Hoje vou ensinar como enlatei o Coder dentro de um container Docker com vários agentes de IA.

Pré-requisitos:

  • Servidor, VPS ou VM com Linux;
  • Docker;

1 – Sobre o Coder

O Coder é uma IDE de desenvolvimento que funciona no navegador.

Ele é inspirado e compatível com o VSCode.

Depois de um tempo tendo que lidar com gestão de projetos usando o método tradicional de instalar tudo no notebook e as vezes sincronizar com o Git, me veio uma ideia: E se a IDE, o projeto, a compilação, testes, agentes de IA pudessem ficar enlatados no Docker?

Com isso eu poderia programar em qualquer computador, smartphone, tablet, delegar tarefas aos agentes, sem precisar manter nenhum deles ligados.

Links:

2 – Guia rápido

Para quem tem pressa!

Crie a rede Docker:

Bash
# Rede de containers
docker network create network_public \
    -d bridge \
    -o com.docker.network.bridge.name=br-net-public \
    -o com.docker.network.driver.mtu=1500 \
    -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \
    --subnet 10.249.0.0/16 \
    --gateway 10.249.255.254;

Criar volume e configuração inicial com senha tulipa_coder (mude para a sua):

Bash
# Diretorio do volume
    # Pasta no HOST
    mkdir -p /storage/coder-ide;

    # Pasta do projeto para mapear em /project do container
    mkdir -p /storage/coder-ide/project;

    # Raiz do sistema
    mkdir -p /storage/coder-ide/.config/code-server;

    # Config inicial
    #(
    #    echo;
    #    echo 'bind-addr: 127.0.0.1:8080';
    #    echo 'auth: password';
    #    echo 'password: tulipa_coder';
    #    echo 'cert: false';
    #    echo;
    #) > /storage/coder-ide/.config/code-server/config.yaml;

    # Ajustar permissoes, login 'coder' uid 1000
    chown -R 1000:1000 /storage/coder-ide;

Container do Coder:

Bash
# Senha de acesso
    PASSWORD="tulipa_coder";

# Atualizar imagem
    docker pull codercom/code-server:latest;

# Renovar/rodar:
    # - Parar atual
    docker container  stop  coder-ide 2>/dev/null;
    docker container  rm    coder-ide 2>/dev/null;

    # - Rodar com imagem renovada
    docker container run \
        -d \
        --user               root \
        --restart            always \
        --name               coder-ide \
        --hostname           coder-ide.intranet.br \
        \
        --cpus                2.0  \
        --cpu-shares         1024 \
        --memory               2g \
        --memory-swap          2g \
        --memory-reservation   1g \
        --shm-size             1g \
        \
        --network            network_public \
        --ip                 10.249.111.201 \
        \
        -p 7280:8080 \
        \
        -v /storage/coder-ide:/root \
        -v /storage/coder-ide:/home/coder \
        -v /storage/coder-ide/project:/project \
        \
        -v /var/run/docker.sock:/var/run/docker.sock \
        \
        -e DEFAULT_WORKSPACE=/project \
        -e DOCKER_USER=root \
        -e PASSWORD=$PASSWORD \
        \
        codercom/code-server:latest \
            --auth password \
            /project;

        # entrypoint: /usr/bin/entrypoint.sh
        # cmd.......: --bind-addr 0.0.0.0:8080

Versão Docker Compose:

YAML – docker-compose.yml
services:
  coder-ide:
    image: codercom/code-server:latest
    container_name: coder-ide
    hostname: coder-ide.intranet.br
    user: root
    restart: always
    networks:
      network_public:
        ipv4_address: 10.249.111.201
    ports:
      - "7280:8080"
    volumes:
      - /storage/coder-ide:/root
      - /storage/coder-ide/log:/var/log
      - /storage/coder-ide:/home/coder
      - /storage/coder-ide/project:/project
      - /var/run/docker.sock:/var/run/docker.sock

    environment:
      DEFAULT_WORKSPACE: /project
      DOCKER_USER: root
      PASSWORD: tulipa_coder
    command:
      - --auth
      - password
      - /project
    cpus: 2.0
    cpu_shares: 1024
    mem_limit: 2g
    memswap_limit: 2g
    mem_reservation: 1g
    shm_size: 1g

networks:
  network_public:
    name: network_public
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-net-public
      com.docker.network.driver.mtu: 1500
      com.docker.network.bridge.gateway_mode_ipv4: nat-unprotected
    ipam:
      config:
        - subnet: 10.249.0.0/16
          gateway: 10.249.255.254

Primeiro acesso: Abra o navegador no endereço do servidor porta HTTP 7280.

3 – Imagem container do pacotão

Agora vou criar uma única imagem juntando tudo que foi feito no capítulo 3.

Crie e entre na pasta coder-bundle:

Script – entrypoint.sh
mkdir -p /root/coder-bundle;
cd       /root/coder-bundle;

Nessa pasta coloque todos os arquivos abaixo:

  • supervisord.conf
  • sshd_config
  • crontab
  • entrypoint.sh
  • Dockerfile

3.1 – Supervisor

Usamos o supervidord para rodar vários softwares no container. Ele será o PID 1 que manterá e reiniciará todos os softwares caso falhem.

Arquivo supervisord.conf

Config – supervisord.conf
[supervisord]
user           = root
nodaemon       = true
pidfile        = /run/supervisord.pid
childlogdir    = /root/log
logfile        = /dev/null
logfile_maxbytes = 0

[unix_http_server]
file           = /var/run/supervisor.sock
chmod          = 0700

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl      = unix:///run/supervisor.sock

[program:sshd]
user           = root
command        = /usr/sbin/sshd -D -e
priority       = 1
directory      = /run
autostart      = true
autorestart    = true
startsecs      = 0
stopwaitsecs   = 2
stdout_logfile = /proc/1/fd/1
stderr_logfile = /proc/1/fd/2
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

[program:coder-server]
user           = root
command = /usr/bin/entrypoint.sh --bind-addr 0.0.0.0:8080 --auth password /project
environment    = HOME="/root",DEFAULT_WORKSPACE="/project"
priority       = 2
directory      = /run
autostart      = true
autorestart    = true
startsecs      = 0
stopwaitsecs   = 2
stdout_logfile = /proc/1/fd/1
stderr_logfile = /proc/1/fd/2
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

[program:cron]
user           = root
command        = /usr/sbin/cron -f -L 8
priority       = 3
directory      = /run
autostart      = true
autorestart    = true
startsecs      = 0
stopwaitsecs   = 2
stdout_logfile = /proc/1/fd/1
stderr_logfile = /proc/1/fd/2
stdout_logfile_maxbytes = 0
stderr_logfile_maxbytes = 0

3.2 – Configuração SSH

Para permitir acesso direto no container por SSH temos que salvar as chaves do servidor em volume e autorizar a entrada como root direto.

O container não possui senha no usuário root, você deverá cadastrar sua chave pública no arquivo trusted_keys:

  • Dentro do container: /root/ssh/trusted_keys
  • No volume: /storage/coder-ide/ssh/trusted_keys

Arquivo sshd_config

Config – sshd_config
VersionAddendum                OpenSSH_12

Protocol                       2
Port                           22
AddressFamily                  any
ListenAddress                  0.0.0.0
ListenAddress                  ::
IPQoS                          lowdelay throughput
Compression                    yes
UseDNS                         no

ClientAliveInterval            3
ClientAliveCountMax            15
TCPKeepAlive                   yes

PubkeyAuthentication           yes
AuthorizedKeysFile	           /root/ssh/trusted_keys .ssh/authorized_keys

HostKey                        /root/ssh/ssh_host_rsa_key
HostKey                        /root/ssh/ssh_host_ecdsa_key
HostKey                        /root/ssh/ssh_host_ed25519_key

PasswordAuthentication         yes
PermitEmptyPasswords           no
PermitListen                   any
PermitRootLogin                yes
KbdInteractiveAuthentication   no
UsePAM                         yes
SyslogFacility                 AUTH
LogLevel                       INFO

PubkeyAuthentication           yes
RekeyLimit                     1G 1h
RequiredRSASize                2048

PrintLastLog                   no
PrintMotd                      no
AcceptEnv                      LANG LC_* COLORTERM NO_COLOR
Subsystem	                     sftp /usr/lib/openssh/sftp-server

AllowAgentForwarding           yes
AllowTcpForwarding             yes
X11Forwarding                  yes
X11DisplayOffset               10
GatewayPorts                   clientspecified
PermitTTY                      yes
PermitTunnel                   no
PermitUserEnvironment          no

Include                        /etc/ssh/sshd_config.d/*.conf

3.3 – Crontab

O plano de crontab com intervalos pre-configurados nos permitirá criar e acionar scripts de automação dentro do nosso projeto.

Vou criar em /root/cron/ pois a pasta /root ficará em volume, preservando assim o projeto e os scripts de automação juntos.

Arquivo crontab

Config – crontab

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# min   hour day month week-day user  program    args...
   0      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/hourly
   0      2    *    *     *     root  run-parts  --regex '.*'  /root/cron/daily
   0      3    *    *     6     root  run-parts  --regex '.*'  /root/cron/weekly
   0      5    1    *     *     root  run-parts  --regex '.*'  /root/cron/monthly
 */1      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/1min
 */5      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/5min
*/10      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/10min
*/15      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/15min
*/30      *    *    *     *     root  run-parts  --regex '.*'  /root/cron/30min
   0      0    *    *     0     root  run-parts  --regex '.*'  /root/cron/sunday
   0      0    *    *     1     root  run-parts  --regex '.*'  /root/cron/monday
   0      0    *    *     2     root  run-parts  --regex '.*'  /root/cron/tuesday
   0      0    *    *     3     root  run-parts  --regex '.*'  /root/cron/wednesday
   0      0    *    *     4     root  run-parts  --regex '.*'  /root/cron/thursday
   0      0    *    *     5     root  run-parts  --regex '.*'  /root/cron/friday
   0      0    *    *     6     root  run-parts  --regex '.*'  /root/cron.saturday

3.4 – Entrypoint

Vou criar um novo entrypoint com supervidord para rodar o Coder Server e o OpenSSH Server, dessa forma poderemos entrar via SSH direto no container.

Arquivo entrypoint.sh

Script – entrypoint.sh
#!/bin/sh

# Funcao de log na stdout
    _log(){
        echo "$(date '+%Y-%m-%d %H:%M:%S'),$(date +%3N) INFO entrypoint $@";
    };

# Codigo principal
    _log "Started";

# Garantir existencia dos diretorios
    mkdir -p /root/log;
    mkdir -p /run;
    mkdir -p /project;

# Logs
    touch /root/log/supervisord.log;
    touch /var/log/lastlog;

# Preparativos do servidor SSH
    # Pasta de configs e chaves do servidor
    mkdir -p /root/ssh;

    # Pasta de configs e chaves do usuario
    mkdir -p /root/.ssh;
    
    # Pasta de trabalho do sshd
    mkdir  -p         /run/sshd;
    chown  root:root  /run/sshd;
    chmod  0755       /run/sshd;

    # Arquivo de cadastro de cahves conviaveis dos clientes
    touch /root/ssh/trusted_keys;
    touch /root/.ssh/authorized_keys;

    # Chaves do servidor SSH
    [ -s /root/ssh/ssh_host_rsa_key ] || {
        _log "SSHD creating key ssh_host_rsa_key";
        ssh-keygen -t rsa   -b 4096 -f /root/ssh/ssh_host_rsa_key -N "";
        chmod 600 /root/ssh/ssh_host_rsa_key;
    };
    [ -s /root/ssh/ssh_host_ecdsa_key ] || {
        _log "SSHD creating key ssh_host_ecdsa_key";
        ssh-keygen -t ecdsa -b 521  -f /root/ssh/ssh_host_ecdsa_key -N "";
        chmod 600 /root/ssh/ssh_host_ecdsa_key;
    };
    [ -s /root/ssh/ssh_host_ed25519_key ] || {
        _log "SSHD creating key ssh_host_ed25519_key";
        ssh-keygen -t ed25519       -f /root/ssh/ssh_host_ed25519_key -N "";
        chmod 600 /root/ssh/ssh_host_ed25519_key;
    };

    # Chave de usuario local pre-provisionada
    [ -s /root/.ssh/id_ed25519 ] || {
        _log "SSHD creating local key id_ed25519";
        ssh-keygen -t ed25519       -f /root/.ssh/id_ed25519 -N "";
        chmod 600 /root/.ssh/id_ed25519;
    };
    
    # Servidor SSH padrao StrictModes=yes requer acesso seguro
    chown   -R  root:root /root;
    chmod  700  /root/ssh;
    chmod  600  /root/ssh/trusted_keys;
    chmod  600  /root/.ssh/authorized_keys;
    chmod  755  /root;

# Preparativos do crontab
    crondirs="
        1min 10min 15min 30min
        hourly daily weekly monthly
        sunday monday tuesday wednesday
        thursday friday saturday
    ";
    for cdir in $crondirs; do
        mkdir -p /root/cron/$cdir;
    done;

# Comando
    EXEC_CMD="$@"
    _log "CMD arg: $EXEC_CMD";

    # Rodar CMD
    if [ "x$EXEC_CMD" = "x" ]; then
        FULLCMD="exec sleep 252288000";
    else
        FULLCMD="exec $EXEC_CMD";
    fi;

    _log "CMD exe: $FULLCMD";
    eval $FULLCMD;

3.5 – Dockerfile

Construtor da imagem. Aditivos:

  • Debian com ferramentas básicas;
  • NodeJS e NPM – versão oficial do Debian (node 22);
  • Agente Claude;
  • Agente OpenCode;
  • Extensões VS Code.

Arquivo Dockerfile

Dockerfile – Dockerfile
# syntax=docker/dockerfile:1.7

# Preparativos dos arquivos externos
#--------------------------------------------------- stage:files
FROM       alpine:latest as STAGE_FILES

RUN        set -eux; \
           apk update; \
           apk upgrade; \
           apk add tar gzip bzip2 xz zstd

RUN        set -eux; \
           mkdir -p /rootfs/opt; \
           mkdir -p /rootfs/etc; \
           mkdir -p /rootfs/etc/ssh

COPY       supervisord.conf  /rootfs/etc/supervisord.conf
COPY       sshd_config       /rootfs/etc/ssh/sshd_config
COPY       crontab           /rootfs/etc/crontab
COPY       entrypoint.sh     /rootfs/opt/entrypoint.sh

RUN        set -eux; \
           chmod +x /rootfs/opt/entrypoint.sh; \
           chown -R root:root /rootfs; \
           cd /rootfs; \
           tar -cpzvf /files.tgz .


# Coder Server pronto, continuando
#--------------------------------------------------- stage:main
FROM       codercom/code-server:latest
USER       root
ENV        LANG=C.UTF-8 \
           LC_ALL=C.UTF-8

# Instalar pacotes basicos
RUN        \
           apt -y update; \
           apt -y upgrade; \
           apt -y dist-upgrade; \
           apt -y full-upgrade; \
           \
           apt -y install --no-install-recommends \
               bash locales tzdata sudo strace \
               openssl wget curl ca-certificates \
               iproute2 htop iputils-ping \
               bzip2 tar gzip xz-utils zstd zip unzip \
               util-linux coreutils procps psmisc \
               brotli gosu sqlite3 ripgrep \
               less logrotate lsof \
               sed grep mawk \
               mc nano jq git \
               file findutils \
               iputils-ping traceroute \
               supervisor

# Instalar aditivos do ambiente de programacao
RUN        apt -y install docker-cli \
               docker-compose \
               docker-buildx \
               rsync \
               openssh-server \
               openssh-sftp-server \
               openssh-client \
               nodejs npm

# Instalar opencode
ENV        OPENCODE_CONFIG_DIR=/root/opencode
ENV        TMPDIR=/tmp
RUN        npm install -g opencode-ai@latest; \
           opencode --version

# Instalar claude-code
RUN        npm install -g @anthropic-ai/claude-code; \
           claude --version

# Arquivos personalizados
COPY       --from=STAGE_FILES  /files.tgz  /tmp/files.tgz

# Ajustes de ambiente
RUN        set -eux; \
           tar -xvf /tmp/files.tgz -C /; \
           rm -f /tmp/files.tgz; \
           locale-gen         en_US.UTF-8; \
           locale-gen         pt_BR.UTF-8; \
           update-locale LANG=en_US.UTF-8; \
           echo 'LANG=en_US.UTF-8' > /etc/default/locale; \
           sed -i '/LANG\|LC_\|LANGUAGE/d' /etc/environment; \
           ( \
               echo; \
               echo; \
               echo "  Coder IDE Container"; \
               echo; \
               echo; \
           ) > /etc/motd; \
           true

# Diretorio padrao inicial
WORKDIR    /project

# Entrypoint para supervidord
# /opt/entrypoint.sh /usr/bin/supervisord -n -c /etc/supervisord.conf
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD        ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]

3.6 – Construção da imagem

Execute o build para construir a imagem:

Bash – build.sh
# Constuir imagem:
docker build . \
    -f Dockerfile \
    -t coder-bundle:latest;

3.7 – Rede

Criando a rede para containers (network_public):

Bash
# Rede de containers
docker network create network_public \
    -d bridge \
    -o com.docker.network.bridge.name=br-net-public \
    -o com.docker.network.driver.mtu=1500 \
    -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \
    --subnet 10.249.0.0/16 \
    --gateway 10.249.255.254;

3.8 – Rodando

Agora basta usar a imagem coder-bundle:latest para ter um super ambiente de desenvolvimento isolado, na nuvem, cheio de bots trabalhadores.

Bash – run.sh
#!/bin/sh

# Nome do container
    NAME="coder-ide";

# Senha de acesso
    PASSWORD="tulipa_coder";

# Nome de DNS
    FQDN="coder.$(hostname -f)";
    #FQDN="coder.seudominio.com";

# Diretorio do volume
    DATADIR="/storage/$NAME";

    # Pasta no HOST
    mkdir  -p  $DATADIR;
    # Pasta do projeto para mapear em /project do container
    mkdir  -p  $DATADIR/project;
    # Raiz do sistema
    mkdir  -p  $DATADIR/.config/code-server;
    # Logs do sistema no volume
    mkdir  -p  $DATADIR/log;
    # Ajustar permissoes, login 'coder' uid 1000
    chown  -R  1000:1000  $DATADIR/project;
    chown  -R  1000:1000  $DATADIR/.config;

# Renovar/rodar:
    # - Parar atual
    docker container  stop  $NAME 2>/dev/null;
    docker container  rm    $NAME 2>/dev/null;

    # - Rodar com imagem renovada
    docker container run \
        -d \
        --user               root \
        --restart            always \
        --name               $NAME \
        --hostname           $NAME.intranet.br \
        \
        --cpus                2.0  \
        --cpu-shares         1024 \
        --memory               2g \
        --memory-swap          2g \
        --memory-reservation   1g \
        --shm-size             1g \
        \
        --network            network_public \
        --ip                 10.249.111.201 \
        \
        -p 7422:22   \
        -p 7480:8080 \
        \
        --tmpfs /run:rw,noexec,nosuid,size=512m \
        --tmpfs /tmp:rw,exec,suid,mode=1777,dev,size=512m \
        \
        -v $DATADIR:/root \
        -v $DATADIR/log:/var/log \
        -v $DATADIR:/home/coder \
        -v $DATADIR/project:/project \
        \
        -v /var/run/docker.sock:/var/run/docker.sock \
        \
        -e DEFAULT_WORKSPACE=/project \
        -e DOCKER_USER=root \
        -e PASSWORD=$PASSWORD \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=web,websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=8080" \
        \
        coder-bundle:latest;

O acesso do container acima está na porta HTTP 7480

Nota: Recomendo configurar o Traefik e escolher um nome real para a variável FQDN, ao funcionar, retire a porta 7480 (HTTP sem criptografia) do container.

O acesso pelo termina web do Coder não é grandes coisas… acesse via SSH para rodar os agentes e comandos com mais liberdade, o acesso pode ser direto na porta SSH 7422.

Bash – Container coder-ide
#
#  Coder IDE Container
#

# root@coder-ide:~# 
ls -1 /usr/local/bin/
    # claude
    # opencode

# Pasta padrao para projetos
cd /project;

3.9 – Extensões

Para instalar extensões via linha de comando, siga os exemplos abaixo:

Bash – Container coder-ide
#
#  Coder IDE Container
#

# Instalar extensoes do VS Code
# - Python Plugin
code-server --force --install-extension ms-python.python;
# - GoLang Plugin
code-server --force --install-extension golang.go;
# - Claude Plugin
code-server --force --install-extension anthropic.claude-code;
# - Docker Plugin
code-server --force --install-extension ms-azuretools.vscode-docker;
# - OpenCode Plugin
code-server --force --install-extension sst-dev.opencode;

4 – Stack Coder e Agentes

Se você não gosta do bundle com muitos programas no mesmo container (entendo, isso deixa a imagem grande e dificulta a escala), podemos rodar o Coder e os agentes separados, cada um no seu container e com suas particularidades.

Eu publiquei as seguintes imagens;

  • tmsoftbrasil/coder-bundle – Coder construído no capítulo 3;
  • tmsoftbrasil/coder-simple – Coder com SSH e crontab, sem agentes;
  • tmsoftbrasil/agent-pi – Agente Pi enlatado;
  • tmsoftbrasil/opencode – Agente OpenCode enlatado;

Vamos rodar os 3 separados mas num mesmo “pod” para criar um ambiente mais adequado para VibeCoding.

Rede:

Bash
# Rede de containers
docker network create network_public \
    -d bridge \
    -o com.docker.network.bridge.name=br-net-public \
    -o com.docker.network.driver.mtu=1500 \
    -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \
    --subnet 10.249.0.0/16 \
    --gateway 10.249.255.254;

Container coder-simple:

Bash – run.sh
#!/bin/sh

# Variaveis
    NAME="coder";
    PASSWORD="tulipa_coder";
    FQDN="coder.$(hostname -f)";
    #FQDN="coder.seudominio.com";

# Diretorio do volume
    DATADIR="/storage/$NAME";
    mkdir  -p  $DATADIR;
    mkdir  -p  $DATADIR/project;
    mkdir  -p  $DATADIR/.config/code-server;
    mkdir  -p  $DATADIR/log;
    chown  -R  1000:1000  $DATADIR/project;
    chown  -R  1000:1000  $DATADIR/.config;

# Renovar/rodar:
    docker container  stop  $NAME 2>/dev/null;
    docker container  rm    $NAME 2>/dev/null;
    docker container run \
        -d \
        --user               root \
        --restart            always \
        --name               $NAME \
        --hostname           $NAME.intranet.br \
        \
        --cpus                2.0  \
        --cpu-shares         1024 \
        --memory               2g \
        --memory-swap          2g \
        --memory-reservation   1g \
        --shm-size             1g \
        \
        --network            network_public \
        --ip                 10.249.111.123 \
        \
        -p 7422:22   \
        \
        --tmpfs /run:rw,noexec,nosuid,size=512m \
        --tmpfs /tmp:rw,exec,suid,mode=1777,dev,size=512m \
        \
        -v $DATADIR:/root \
        -v $DATADIR/log:/var/log \
        -v $DATADIR:/home/coder \
        -v $DATADIR/project:/project \
        \
        -e DEFAULT_WORKSPACE=/project \
        -e DOCKER_USER=root \
        -e PASSWORD=$PASSWORD \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=web,websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=8080" \
        \
        coder-simple:latest;

Container opencode:

Bash – run.sh
#!/bin/sh

# Variaveis
    NAME="opencode-senior";
    IMAGE="tmsoftbrasil/opencode:latest";

# Diretorio de dados persistentes:
    DATADIR=/storage/$NAME;
    # Pastas de volumes montados
    # na pasta principal do volume no host
    mkdir -p $DATADIR;
    mkdir -p $DATADIR/data;
    mkdir -p $DATADIR/cache;
    mkdir -p $DATADIR/workspace;

# Renovar/rodar
    docker container rm -f $NAME 2>/dev/null
    #    --read-only
    docker container run \
        -d \
        --user               root \
        --restart            always \
        --name               $NAME \
        --hostname           $NAME.intranet.br \
        \
        --cpus                2.0  \
        --cpu-shares         1024 \
        --memory               2g \
        --memory-swap          2g \
        --memory-reservation   1g \
        --shm-size             1g \
        \
        --network            network_public \
        --ip                 10.249.111.134 \
        -p                   9422:22 \
        \
        -v $DATADIR/data:/data \
        -v $DATADIR/cache:/cache \
        -v $DATADIR/workspace:/workspace \
        \
        -v /storage/coder/project:/project \
        -w /project \
        \
        $IMAGE;

x

.

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com

Uma só mão não aplaude
Provérbio Árabe