├── scripts ├── open_ports.sh └── apt_pkgs.sh ├── config ├── microsoft-prod.list ├── config.yaml ├── jail.local ├── sources10.list ├── sources.list ├── nginx.conf └── .zshrc ├── .gitignore ├── init.sh ├── certs └── generate_certs.sh ├── openssl.yaml ├── pkgs ├── dependencies.txt └── sha256sum.txt ├── .env.template ├── openssl.dockerfile ├── license.md ├── code-server.yaml ├── code-server.nginx.yaml ├── readme.md └── Dockerfile /scripts/open_ports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | netstat --version 4 | netstat -tunlp 5 | 6 | set +x -------------------------------------------------------------------------------- /config/microsoft-prod.list: -------------------------------------------------------------------------------- 1 | deb [arch=amd64] https://packages.microsoft.com/debian/10/prod buster main -------------------------------------------------------------------------------- /config/config.yaml: -------------------------------------------------------------------------------- 1 | bind-addr: 0.0.0.0:8080 2 | auth: password 3 | password: <> 4 | cert: true 5 | -------------------------------------------------------------------------------- /config/jail.local: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | # Ban hosts for one hour: 3 | bantime = 3600 4 | 5 | # Override /etc/fail2ban/jail.d/00-firewalld.conf: 6 | banaction = iptables-multiport 7 | 8 | [sshd] 9 | enabled = true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # --------------- 2 | # GIT IGNORE 3 | # --------------- 4 | 5 | # ide:: 6 | .vscode/ 7 | 8 | # securables:: 9 | .env 10 | certs/*.pem 11 | certs/*.crt 12 | certs/*.csr 13 | certs/*.key 14 | 15 | # pkgs:: 16 | pkgs/*.deb 17 | 18 | -------------------------------------------------------------------------------- /scripts/apt_pkgs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd ../pkgs/ 4 | 5 | printf "[wget] fetch pkg dependencies: \n" 6 | wget -i ../pkgs/dependencies.txt 7 | 8 | printf "[sha256sum] compute hash diff output: \n" 9 | sha256sum *.deb >> sha256sum.tmp 10 | diff sha256sum.tmp sha256sum.txt 11 | 12 | set +x; 13 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | which code-server 4 | 5 | code-server \ 6 | --disable-telemetry \ 7 | --cert=/config/certs/ssl.crt \ 8 | --cert-key=/config/certs/ssl.key \ 9 | --config=/config/config.yaml \ 10 | --user-data-dir=/config/data \ 11 | --extensions-dir=/config/extensions 12 | 13 | set +x; 14 | -------------------------------------------------------------------------------- /certs/generate_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [[ $(which openssl) != "/usr/bin/openssl" ]] 4 | then 5 | printf "OpenSSL not installed, distribution agnostic package required." 6 | exit 125 7 | fi 8 | 9 | openssl req \ 10 | -nodes \ 11 | -new \ 12 | -x509 \ 13 | -keyout ssl.key \ 14 | -out ssl.crt \ 15 | -subj '/CN=localhost/O=code/C=US' 16 | 17 | set +x 18 | -------------------------------------------------------------------------------- /openssl.yaml: -------------------------------------------------------------------------------- 1 | # ------------ 2 | # OpenSSL Self-Signed Certs 3 | # Base Tag: debian:buster 4 | # ------------ 5 | 6 | version: "3.3" 7 | 8 | services: 9 | certs: 10 | build: 11 | context: . 12 | dockerfile: openssl.dockerfile 13 | image: openssl.certs:latest 14 | container_name: code.server.runtime.certs 15 | volumes: 16 | - ./certs:/tmp 17 | 18 | # ------------- 19 | -------------------------------------------------------------------------------- /config/sources10.list: -------------------------------------------------------------------------------- 1 | # deb https://snapshot.debian.org/archive/debian/20210721T000000Z buster main 2 | deb https://deb.debian.org/debian buster main 3 | # deb https://snapshot.debian.org/archive/debian-security/20210721T000000Z bust> 4 | deb https://security.debian.org/debian-security buster/updates main 5 | # deb https://snapshot.debian.org/archive/debian/20210721T000000Z buster-update> 6 | deb https://deb.debian.org/debian buster-updates main 7 | -------------------------------------------------------------------------------- /pkgs/dependencies.txt: -------------------------------------------------------------------------------- 1 | https://deb.debian.org/debian/pool/main/a/apt/apt-transport-https_1.8.2.3_all.deb 2 | https://deb.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20210119_all.deb 3 | https://deb.debian.org/debian/pool/main/o/openssl/libssl-dev_1.1.1d-0+deb10u7_amd64.deb 4 | https://deb.debian.org/debian/pool/main/o/openssl/libssl1.1_1.1.1d-0+deb10u7_amd64.deb 5 | https://deb.debian.org/debian/pool/main/o/openssl/openssl_1.1.1k-1+deb11u1_amd64.deb 6 | -------------------------------------------------------------------------------- /config/sources.list: -------------------------------------------------------------------------------- 1 | # deb https://snapshot.debian.org/archive/debian/20211220T000000Z bullseye main 2 | deb https://deb.debian.org/debian bullseye main 3 | # deb https://snapshot.debian.org/archive/debian-security/20211220T000000Z bullseye-security main 4 | deb https://security.debian.org/debian-security bullseye-security main 5 | # deb https://snapshot.debian.org/archive/debian/20211220T000000Z bullseye-updates main 6 | deb https://deb.debian.org/debian bullseye-updates main 7 | -------------------------------------------------------------------------------- /pkgs/sha256sum.txt: -------------------------------------------------------------------------------- 1 | d2a427d1738562641607603fe5d615499b7e118efb3923ae84fa36bb7ca54fb1 apt-transport-https_1.8.2.3_all.deb 2 | b2d488ad4d8d8adb3ba319fc9cb2cf9909fc42cb82ad239a26c570a2e749c389 ca-certificates_20210119_all.deb 3 | fb6e5dbe9a36aa7b3dcddf996ec1d65a64ea8f6aa47581b9aa58014660b807d1 libssl-dev_1.1.1d-0+deb10u7_amd64.deb 4 | 49e1171928d3930fb8ba5659a80e8862d7d585c6d750acb6520b1c133ac00b29 libssl1.1_1.1.1d-0+deb10u7_amd64.deb 5 | ed998755dabb96ffe107c2d41ce685ecbb4fa200f7825ff82c1092f8334bf3cb openssl_1.1.1k-1+deb11u1_amd64.deb 6 | -------------------------------------------------------------------------------- /.env.template: -------------------------------------------------------------------------------- 1 | # METADATA 2 | CODE_VERSION=3.12.0 3 | 4 | # ENDPOINT PORT MAPPING 5 | VIRTUAL_HOST= 6 | VIRTUAL_PORT= 7 | HTTPS_PROXY= 8 | 9 | # CONFIG MOUNTS 10 | HOST_CONFIG_PATH=./config 11 | HOST_LOG_PATH=./logs 12 | 13 | # DATA MOUNTS 14 | HOST_CODE_PATH= 15 | CODE_PATH= 16 | 17 | # PREFERENCES 18 | TZ= 19 | SUDO_PASSWORD= 20 | 21 | # USER 22 | DEFAULT_USER=code 23 | PUID=1000 24 | PGID=1000 25 | 26 | # DOCKER PROPS 27 | HOST_GID=999 28 | TLS_CERTDIR=/certs 29 | -------------------------------------------------------------------------------- /openssl.dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster 2 | 3 | # -------------- 4 | # Package: APT Transport HTTPs 5 | # -------------- 6 | COPY pkgs /tmp/pkgs 7 | RUN dpkg -i /tmp/pkgs/*.deb 8 | 9 | # -------------- 10 | # Repos: Replace Sources, APT over HTTPs 11 | # -------------- 12 | COPY config/sources.list /etc/apt/sources.list 13 | 14 | # -------------- 15 | # Package: Openssl 16 | # -------------- 17 | RUN apt-get update && \ 18 | apt install -y \ 19 | openssl && \ 20 | apt clean all 21 | 22 | WORKDIR /tmp 23 | 24 | CMD [ "/bin/sh", "-c", "/tmp/generate_certs.sh" ] 25 | -------------------------------------------------------------------------------- /config/nginx.conf: -------------------------------------------------------------------------------- 1 | events {} 2 | http { 3 | server { 4 | listen [::]:80; 5 | location / { 6 | return 301 https://$host$request_uri; 7 | } 8 | } 9 | 10 | server { 11 | server_name $host; 12 | listen [::]:443 ssl default_server; 13 | ssl_certificate /etc/nginx/certs/ssl.crt; 14 | ssl_certificate_key /etc/nginx/certs/ssl.key; 15 | ssl_protocols TLSv1.1 TLSv1.2; 16 | ssl_prefer_server_ciphers on; 17 | ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5; 18 | 19 | location / { 20 | proxy_pass http://code:8443/; 21 | proxy_set_header Host $host; 22 | proxy_set_header X-Real-IP $remote_addr; 23 | proxy_set_header Upgrade $http_upgrade; 24 | proxy_set_header Connection upgrade; 25 | proxy_set_header Accept-Encoding gzip; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Sar Malik. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /code-server.yaml: -------------------------------------------------------------------------------- 1 | # ---------------- 2 | # Code Server + HTTPs Proxy 3 | # Base Tag: linuxserver/code-server:amd64-latest 4 | # Docs: https://hub.docker.com/r/linuxserver/code-server 5 | # ---------------- 6 | 7 | version: "3.3" 8 | 9 | services: 10 | code: 11 | build: 12 | context: . 13 | dockerfile: dockerfile 14 | args: 15 | - HOST_GID=${HOST_GID} 16 | - DEFAULT_USER=${DEFAULT_USER} 17 | - SUDO_PASSWORD=${SUDO_PASSWORD} 18 | - CODE_VERSION=${CODE_VERSION} 19 | image: code.server.sdk 20 | container_name: code.server 21 | privileged: false 22 | user: ${DEFAULT_USER} 23 | env_file: .env 24 | ports: 25 | - ${VIRTUAL_PORT}:8080 26 | - "5000-5010:5000-5010" 27 | - "8000-8010:8000-8010" 28 | networks: 29 | - code_server 30 | volumes: 31 | - ${HOST_CODE_PATH}:${CODE_PATH}:z 32 | - ./config/config.yaml:/config/config.yaml:ro 33 | - ./certs:/config/certs:ro 34 | - config_data:/config/data 35 | - config_extensions:/config/extensions 36 | - logs:/config/data/logs 37 | - logs:/home/${DEFAULT_USER}/.config/code-server/coder-logs 38 | - /var/run/docker.sock:/var/run/docker.sock 39 | deploy: 40 | resources: 41 | limits: 42 | cpus: '8' 43 | memory: 32G 44 | restart_policy: 45 | condition: on-failure 46 | delay: 15s 47 | max_attempts: 5 48 | window: 60s 49 | 50 | volumes: 51 | config: 52 | config_data: 53 | config_extensions: 54 | logs: 55 | 56 | networks: 57 | code_server: 58 | driver: bridge 59 | -------------------------------------------------------------------------------- /code-server.nginx.yaml: -------------------------------------------------------------------------------- 1 | # ---------------- 2 | # Code Server + Nginx Reverse Proxy 3 | # Base Tag: linuxserver/code-server:amd64-latest 4 | # Docs: https://hub.docker.com/r/linuxserver/code-server 5 | # ---------------- 6 | 7 | version: "3.7" 8 | 9 | services: 10 | proxy: 11 | image: jwilder/nginx-proxy 12 | container_name: code.proxy 13 | env_file: .env 14 | ports: 15 | - ${VIRTUAL_PORT}:443 16 | networks: 17 | - code_server 18 | volumes: 19 | - ./certs:/etc/nginx/certs:ro 20 | - ./vhostd:/etc/nginx/vhost.d 21 | - ./html:/usr/share/nginx/html 22 | - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro 23 | - /var/run/docker.sock:/tmp/docker.sock:ro 24 | deploy: 25 | resources: 26 | limits: 27 | cpus: '0.5' 28 | memory: 256M 29 | restart_policy: 30 | condition: on-failure 31 | delay: 5s 32 | max_attempts: 25 33 | window: 15s 34 | 35 | code: 36 | build: 37 | context: . 38 | args: 39 | - DOCKER_HOST_GID=${DOCKER_HOST_GID} 40 | - DEFAULT_USER=${DEFAULT_USER} 41 | image: code.server.sdk 42 | container_name: code.server 43 | privileged: false 44 | env_file: .env 45 | command: code-server --disable-telemetry 46 | expose: 47 | - 8443 48 | ports: 49 | - "5000-5010:5000-5010" 50 | - "8000-8010:8000-8010" 51 | networks: 52 | - code_server 53 | volumes: 54 | - ${HOST_CODE_PATH}:${CODE_PATH}:z 55 | - ${HOST_CONFIG_PATH}:/home/coder/.config 56 | - ${HOST_CONFIG_PATH}:/config/.config 57 | - ${HOST_CONFIG_PATH}/data:/config/data 58 | - ${HOST_CONFIG_PATH}/workspace:/config/workspace 59 | - ${HOST_CONFIG_PATH}/extensions:/config/extensions 60 | - ${HOST_CONFIG_PATH}/extensions:/config/.local/share/code-server/extensions 61 | - ${HOST_LOG_PATH}:/config/.local/share/code-server/coder-logs 62 | - /var/run/docker.sock:/var/run/docker.sock 63 | depends_on: 64 | - proxy 65 | deploy: 66 | resources: 67 | limits: 68 | cpus: '8' 69 | memory: 32G 70 | restart_policy: 71 | condition: on-failure 72 | delay: 15s 73 | max_attempts: 5 74 | window: 60s 75 | 76 | networks: 77 | code_server: 78 | driver: bridge 79 | -------------------------------------------------------------------------------- /config/.zshrc: -------------------------------------------------------------------------------- 1 | # If you come from bash you might have to change your $PATH. 2 | # export PATH=$HOME/bin:/usr/local/bin:$PATH 3 | 4 | # Path to your oh-my-zsh installation. 5 | export ZSH="/config/.oh-my-zsh" 6 | 7 | # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. 8 | # Initialization code that may require console input (password prompts, [y/n] 9 | # confirmations, etc.) must go above this block, everything else may go below. 10 | if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then 11 | source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" 12 | fi 13 | 14 | # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. 15 | [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh 16 | 17 | # Set name of the theme to load --- if set to "random", it will 18 | # load a random theme each time oh-my-zsh is loaded, in which case, 19 | # to know which specific one was loaded, run: echo $RANDOM_THEME 20 | # See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes 21 | ZSH_THEME="powerlevel10k/powerlevel10k" 22 | POWERLEVEL9K_MODE="awesome-patched" 23 | 24 | # Set list of themes to pick from when loading at random 25 | # Setting this variable when ZSH_THEME=random will cause zsh to load 26 | # a theme from this variable instead of looking in ~/.oh-my-zsh/themes/ 27 | # If set to an empty array, this variable will have no effect. 28 | # ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) 29 | 30 | # Uncomment the following line to use case-sensitive completion. 31 | # CASE_SENSITIVE="true" 32 | 33 | # Uncomment the following line to use hyphen-insensitive completion. 34 | # Case-sensitive completion must be off. _ and - will be interchangeable. 35 | # HYPHEN_INSENSITIVE="true" 36 | 37 | # Uncomment the following line to disable bi-weekly auto-update checks. 38 | # DISABLE_AUTO_UPDATE="true" 39 | 40 | # Uncomment the following line to automatically update without prompting. 41 | # DISABLE_UPDATE_PROMPT="true" 42 | 43 | # Uncomment the following line to change how often to auto-update (in days). 44 | # export UPDATE_ZSH_DAYS=13 45 | 46 | # Uncomment the following line if pasting URLs and other text is messed up. 47 | # DISABLE_MAGIC_FUNCTIONS=true 48 | 49 | # Uncomment the following line to disable colors in ls. 50 | # DISABLE_LS_COLORS="true" 51 | 52 | # Uncomment the following line to disable auto-setting terminal title. 53 | # DISABLE_AUTO_TITLE="true" 54 | 55 | # Uncomment the following line to enable command auto-correction. 56 | # ENABLE_CORRECTION="true" 57 | 58 | # Uncomment the following line to display red dots whilst waiting for completion. 59 | # COMPLETION_WAITING_DOTS="true" 60 | 61 | # Uncomment the following line if you want to disable marking untracked files 62 | # under VCS as dirty. This makes repository status check for large repositories 63 | # much, much faster. 64 | # DISABLE_UNTRACKED_FILES_DIRTY="true" 65 | 66 | # Uncomment the following line if you want to change the command execution time 67 | # stamp shown in the history command output. 68 | # You can set one of the optional three formats: 69 | # "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" 70 | # or set a custom format using the strftime function format specifications, 71 | # see 'man strftime' for details. 72 | # HIST_STAMPS="mm/dd/yyyy" 73 | 74 | # Would you like to use another custom folder than $ZSH/custom? 75 | # ZSH_CUSTOM=/path/to/new-custom-folder 76 | 77 | # Which plugins would you like to load? 78 | # Standard plugins can be found in ~/.oh-my-zsh/plugins/* 79 | # Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/ 80 | # Example format: plugins=(rails git textmate ruby lighthouse) 81 | # Add wisely, as too many plugins slow down shell startup. 82 | plugins=( 83 | git 84 | zsh-syntax-highlighting 85 | zsh-autosuggestions 86 | zsh-completions 87 | history-search-multi-word 88 | ) 89 | 90 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh 91 | source $ZSH/oh-my-zsh.sh 92 | 93 | # User configuration 94 | 95 | # export MANPATH="/usr/local/man:$MANPATH" 96 | 97 | # You may need to manually set your language environment 98 | # export LANG=en_US.UTF-8 99 | 100 | # Preferred editor for local and remote sessions 101 | # if [[ -n $SSH_CONNECTION ]]; then 102 | # export EDITOR='vim' 103 | # else 104 | # export EDITOR='mvim' 105 | # fi 106 | 107 | # Compilation flags 108 | # export ARCHFLAGS="-arch x86_64" 109 | 110 | # Set personal aliases, overriding those provided by oh-my-zsh libs, 111 | # plugins, and themes. Aliases can be placed here, though oh-my-zsh 112 | # users are encouraged to define aliases within the ZSH_CUSTOM folder. 113 | # For a full list of active aliases, run `alias`. 114 | # 115 | # Example aliases 116 | # alias zshconfig="mate ~/.zshrc" 117 | # alias ohmyzsh="mate ~/.oh-my-zsh" 118 | alias vi="vim" 119 | 120 | # Set default user prop 121 | DEFAULT_USER=$(whoami) 122 | 123 | # Default Exports 124 | export PATH=/usr/local/lib/python:$PATH 125 | export PATH=/config/.local/bin:$PATH 126 | export PATH=/home/$USER/.local/bin:$PATH 127 | export PATH=/config/.dotnet/tools:$PATH 128 | export PATH=/home/linuxbrew/.linuxbrew/bin:$PATH 129 | 130 | # Enable for nvidia-container-runtime CUDA deployments 131 | # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64 132 | # if [ -z $LD_LIBRARY_PATH ]; then 133 | # LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:/usr/local/cuda-10.0/lib 134 | # else 135 | # LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-10.0/lib64:/usr/local/cuda-10.0/lib 136 | # fi 137 | # export LD_LIBRARY_PATH 138 | # export PATH=/usr/local/cuda-10.0/bin${PATH:+:${PATH}} 139 | # export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} 140 | 141 | # Configure Ranger Path 142 | alias ranger='ranger --choosedir=$HOME/.rangerdir; LASTDIR=`cat $HOME/.rangerdir`; cd "$LASTDIR"' 143 | 144 | # Useful scripts 145 | 146 | # Url: Creates url shortcuts 147 | # Props 148 | function url { 149 | if [ "$#" -ne 2 ]; then 150 | echo "[url]: Parsing website title for $1" 151 | title=`wget -qO- $1 | \ 152 | perl -l -0777 -ne 'print $1 if /\s*(.*?)\s*<\/title/si'` 153 | printf "[Internet Shortcut]\nURL=$1\r\n" >> ./$title.url 154 | fi 155 | #else 156 | # printf "[Internet Shortcut]\nURL=$2\r\n" >> ./$1.url 157 | #fi 158 | } 159 | 160 | # END OF ZSHRC -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Containerized Code Server with SSL & Dev Tooling 2 | 3 | Launch your own [Code Server](https://github.com/cdr/code-server) container with preloaded dev tools (sdks, npm packages, CLIs etc) for an efficient and securely accessible Web IDE in your homelab! 4 | 5 | ![code-server](https://raw.githubusercontent.com/cdr/code-server/main/docs/assets/screenshot.png) 6 | 7 | ## Getting Started 8 | 9 | Clone this repo on the server with `docker` or `podman` configured. It's recommended to attach mount points for storing your codebase isolated from the container runtime for redundancy and failover management. 10 | 11 | Next, set the required environment variables and data paths using the provided [.env.template](.env.template) replicated to `.env` (note: default exclude declared in .gitignore). 12 | 13 | Persistent storage for extensions and vscode settings can also be enabled by mapping `HOST_*` variables for convenience against container restarts. 14 | 15 | Here's an example of what you'll need to define in `.env`: 16 | ``` 17 | VIRTUAL_HOST=10.0.0.1 18 | VIRTUAL_PORT=8555 19 | 20 | HOST_CONFIG_PATH=./config 21 | HOST_LOG_PATH=./logs 22 | 23 | HOST_CODE_PATH=/mnt/codebase 24 | CODE_PATH=/code 25 | 26 | TZ=America/New_York 27 | SUDO_PASSWORD= 28 | ``` 29 | 30 | An additional [config.yaml](config.yaml) is required for `code-server` mapped using `path:ro` volume. The container will auto-generate a file if none is provided. 31 | 32 | ``` 33 | bind-addr: 0.0.0.0:8080 34 | auth: password 35 | password: <> 36 | cert: false 37 | ``` 38 | 39 | Nginx is used to reroute traffic from `[::]:80` to upstream HTTPS port `[::]:8443` with self-signed SSL certificates. Checkout and run the [generate_certs.sh](scripts/generate_certs.sh) script to emit the required certificates with signing key using `openssl`. 40 | 41 | Place both the [nginx.conf](config/nginx.conf) and certs under the paths defined in `code-server.yaml`. 42 | 43 | ```nginx.conf 44 | listen [::]:443 ssl default_server; 45 | ssl_certificate /etc/nginx/certs/ssl.crt; 46 | ssl_certificate_key /etc/nginx/certs/ssl.key; 47 | ssl_protocols TLSv1.1 TLSv1.2; 48 | ssl_prefer_server_ciphers on; 49 | ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5; 50 | ``` 51 | 52 | Finally, deploy the container stack on the docker host using the command `docker-compose -f code-server.yaml up`. It may take 15-20 minutes depending on your hardware and network bandwidth for the initial build. The dockerfile pre-configures a number of devtools and updates the base image packages. 53 | 54 | To comply with Docker CIS, resource limits are defined on each of the containers but can be customized to your hardware in the compose [code-server.yaml](code-server.yaml) file. 55 | 56 | An alternative compose file [code-server.https.yaml](code-server.https.yaml) is provided with automatic configuration of NGINX proxy using [steveltn/https-portal](https://hub.docker.com/r/steveltn/https-portal). 57 | 58 | ## Pre-Installed Dev Tools 59 | 60 | Here's a quick overview of what the `dockerfile` does to extend [debian:buster](https://hub.docker.com/_/debian) base image. This allows containers to be rapidly deployed and scaled up for usage on dev teams with tooling ready to go. 61 | 62 | The output image includes SDKs for cloud native app development workloads such as React, Node, C#, AWS and Azure Cloud CLIs. 63 | 64 | ``` 65 | * Cloud CLIs 66 | * AWS CLI Tools 67 | * aws-shell 68 | * amplify cli 69 | * Azure CLI 70 | * NPM packages 71 | * yarn (upstream) 72 | * gatsby-cli 73 | * gulp 74 | * create-react-app 75 | * @storybook/cli 76 | * .NET Core SDK and Runtime 77 | * 5.0.0 78 | * 3.1.0 79 | * 2.1.0 80 | * Python global env 81 | * python3 python3-pip python3-dev 82 | * Ubuntu apt packages 83 | * Networking 84 | * wget 85 | * apt-transport-https 86 | * libssl-dev libffi-dev 87 | * Tools 88 | * ranger 89 | * tree 90 | * unzip 91 | * ansible 92 | * vim 93 | * htop 94 | * iputils-ping 95 | * OS/Misc 96 | * systemd 97 | * build-essential 98 | * ffmpeg 99 | * youtube-dl 100 | * chromium-browser 101 | * Default shell --> zsh/oh-my-zsh 102 | * zsh-syntax-highlighting 103 | * zsh-autosuggestions 104 | * zsh-completions 105 | * history-search-multi-word 106 | ``` 107 | 108 | Refer to the [Dockerfile](dockerfile) for image layers. 109 | 110 | ### Remote Debugging 111 | 112 | By default the `dockerfile` and `code-server.yaml` are set to expose port ranges `5000-5010` and `8000-8010` commonly used for web app development. Customize this for your workload such as React, Gatsby, Angular, Django, etc. to allow for remote debugging HTTP instances that are running inside the container. 113 | 114 | To allow external access on node frameworks that depend `http-server` (instantiated with `npm` or `yarn`) you may need to also update your `package.json` and bind the runtime to the host ip instead of localhost. 115 | 116 | Here are a few common examples: 117 | 118 | ```json 119 | { 120 | "scripts": { 121 | "ng:start": "ng serve --host 0.0.0.0", 122 | "npm:start": "http-server --host 0.0.0.0", 123 | "gatsby:start": "gatsby develop --host 0.0.0.0" 124 | } 125 | } 126 | ``` 127 | 128 | Alternatively, if you'd prefer not to expose ports, check out the [vscode-browser-preview](https://github.com/auchenberg/vscode-browser-preview/) extension which enables `chromium` based inspection and debugging within the container itself. 129 | 130 | ## Security Considerations 131 | 132 | As the base image extends `debian:buster`, additional steps have been taken to add security measures with `hosts` file, `fail2ban` and `clamav` packages preloaded. These are precautionary against attacks but insufficient against (un)known breaches. 133 | 134 | **APT over HTTP(s)** 135 | 136 | MITM attacks while unlikely by default due to PGP signature verification of repos, can be further averted with `apt-transport-https` package. Vulnerable networks can still reveal user transmit/receive of debian updates, to further anonymize traffic install the package `apt-transport-tor` and use for `tor://` prefix on repos for apt over `tor.service` socks proxy. 137 | 138 | **Log Analytics** 139 | 140 | It's strongly recommended to configure a remote syslog daemon for log analytics with `auditd` enabled, here's our guide on using solutions such as [Graylog2](https://ix.quant.one/GraylogAnsible). 141 | 142 | **Ports** 143 | 144 | There's a wide range of tcp ports exposed and mapped directly to the host for remote debugging apps running inside the container. By default, only the `code-server` is allocated on ports `8443` and `localhost:8080`. 145 | 146 | ```bash 147 | $ netstat -tnlp 148 | 149 | Active Internet connections (only servers) 150 | Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name 151 | tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN 299/node 152 | tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN - 153 | ``` 154 | 155 | For dev workloads outside of a homelab or private cloud behind firewalls, using an nginx reverse proxy with HTTPS and auth redirects is vital to preventing sensitive code exposure. 156 | 157 | ### Workarounds 158 | 159 | **File Watcher Limit** 160 | 161 | Containers inherit the default file watcher limit from the docker host. To set an increased value persistently, run the following command on the server and reboot. 162 | 163 | ```bash 164 | $ echo "fs.inotify.max_user_watches = 524288" >> /etc/sysctl.conf 165 | $ sudo sysctl -p 166 | ``` 167 | 168 | **Docker in Docker** 169 | 170 | To run containers using rootless mode inside the `code-server` container itself, set `gid` as an environment variable (in `.env`) matching the docker host before building the image. This will add the default `$USER` to the `docker` group with the correct permissions to the `docker.sock`. 171 | 172 | ```env 173 | DOCKER_HOST_GID=999 174 | ``` 175 | 176 | ```bash 177 | $ ls -l /var/run/docker.sock 178 | srw-rw----. 1 root docker 0 Dec 22 17:52 /var/run/docker.sock 179 | 180 | $ id $USER 181 | ...999(docker) 182 | 183 | # Manually rebuild 184 | $ docker build --build-arg DOCKER_HOST_GID=999 --build-arg DEFAULT_USER=abc -t . 185 | 186 | # Use docker-compose to build and deploy automatically 187 | $ docker-compose -f code-server.yaml up 188 | ``` 189 | 190 | Inside the container, you should no longer receive permission errors upon calling docker comands without sudo. 191 | 192 | ```bash 193 | $ docker run hello-world 194 | docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create: dial unix /var/run/docker.sock: connect: permission denied. 195 | See 'docker run --help'. 196 | 197 | # Built with GID= 198 | $ docker run hello-world 199 | ``` 200 | 201 | ## Contributing 202 | 203 | Contributions including forks and reporting issues are welcome. Be sure to include the output of `$ uname -a` of your container host or `docker-compose` configuration and a detailed description to allow for replication. 204 | 205 | ## License 206 | 207 | This project is made available under the MIT License. For more information, refer to [license.md](license.md). 208 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # @diff upstream:: 2 | # @repo https://github.com/sar/neovim-container.git 3 | 4 | # -------------- 5 | # BASE IMAGE 6 | # -------------- 7 | FROM debian:11.5 8 | 9 | # -------------- 10 | # ARGS 11 | # -------------- 12 | ARG HOST_GID 13 | ARG DEFAULT_USER 14 | ARG SUDO_PASSWORD 15 | ARG HTTPS_PROXY 16 | 17 | # >= 16,18 18 | ARG RELEASE_NODE=18 19 | ARG RELEASE_BIN_NPM=9.3.0 20 | 21 | # @diff code-server:: 22 | # @repo https://github.com/sar/vs-code-container-with-ssl.git 23 | ARG RELEASE_CODE_SERVER=4.9.1 24 | 25 | # @diff upstream:: 26 | # @repo https://github.com/sar/neovim-container.git 27 | 28 | ARG RELEASE_BIN_DOTNET_DBG=2.2.0-961 29 | ARG RELEASE_BIN_LAMBDA_DOTNET=6.9.0 30 | ARG RELEASE_BIN_AWS_AMPLIFY_CLI=10.6.1 31 | ARG RELEASE_BIN_TERRAFORMER=0.8.22 32 | ARG RELEASE_BIN_GITHUB=2.4.0 33 | ARG RELEASE_BIN_DIVE=0.9.2 34 | ARG RELEASE_BIN_GITUI=v0.20.1 35 | ARG RELEASE_BIN_VERCO=v6.7.0 36 | 37 | # -------------- 38 | # USER 39 | # -------------- 40 | RUN useradd ${DEFAULT_USER} && \ 41 | usermod -aG sudo ${DEFAULT_USER} && \ 42 | echo ${DEFAULT_USER}:${SUDO_PASSWORD} | chpasswd && \ 43 | mkdir /home/${DEFAULT_USER} && \ 44 | chown -R ${DEFAULT_USER}:${DEFAULT_USER} /home/${DEFAULT_USER} 45 | 46 | # -------------- 47 | # Package: APT Transport HTTPs 48 | # -------------- 49 | COPY pkgs /tmp/pkgs 50 | RUN dpkg -i /tmp/pkgs/*.deb 51 | 52 | # -------------- 53 | # Repos: Replace Sources, APT over HTTPs 54 | # -------------- 55 | COPY pkgs/sources.list /etc/apt/sources.list 56 | 57 | # -------------- 58 | # Update: System Packages, Dependencies 59 | # -------------- 60 | RUN apt-get update && \ 61 | apt-get upgrade -y && \ 62 | apt install -y \ 63 | ansible \ 64 | bash \ 65 | build-essential \ 66 | curl \ 67 | dirmngr \ 68 | fontconfig \ 69 | g++ \ 70 | gcc \ 71 | gnupg \ 72 | gnupg-agent \ 73 | golang \ 74 | htop \ 75 | jq \ 76 | proxychains4 \ 77 | chromium \ 78 | libxcursor-dev \ 79 | libxdamage-dev \ 80 | libxi-dev \ 81 | libxtst-dev \ 82 | libnss3-dev \ 83 | libxcb-dri3-dev \ 84 | libffi-dev \ 85 | libx11-dev \ 86 | libxkbfile-dev \ 87 | libsecret-1-dev \ 88 | libvips-dev \ 89 | libvips42 \ 90 | man \ 91 | pkg-config \ 92 | proxychains \ 93 | ranger \ 94 | ripgrep \ 95 | sed \ 96 | software-properties-common \ 97 | sshpass \ 98 | sudo \ 99 | systemd \ 100 | tar \ 101 | tree \ 102 | trash-cli \ 103 | unzip \ 104 | vim \ 105 | wget 106 | 107 | # -------------- 108 | # SEC: Fail2ban 109 | # -------------- 110 | USER root 111 | RUN apt install -y fail2ban && \ 112 | wget https://raw.githubusercontent.com/sar/vs-code-container-with-ssl/main/config/jail.local -O /etc/fail2ban/jail.local && \ 113 | systemctl enable fail2ban 114 | 115 | # -------------- 116 | # SEC: ClamAV 117 | # -------------- 118 | RUN apt install -y clamav clamav-daemon && \ 119 | freshclam 120 | 121 | # -------------- 122 | # Python3 123 | # -------------- 124 | RUN apt install -y \ 125 | python3 \ 126 | python3-dev \ 127 | python3-pip \ 128 | python3-venv 129 | 130 | # -------------- 131 | # NodeJS 132 | # -------------- 133 | RUN wget https://raw.githubusercontent.com/nodesource/distributions/master/deb/setup_${RELEASE_NODE}.x \ 134 | -O /tmp/nodejs_${RELEASE_NODE}_setup.sh && \ 135 | chmod +x /tmp/nodejs_${RELEASE_NODE}_setup.sh && \ 136 | /tmp/nodejs_${RELEASE_NODE}_setup.sh && \ 137 | apt install -y nodejs && \ 138 | node -v && npm -v \ 139 | npm config set python python3 140 | 141 | # @diff code-server:: 142 | # @repo https://github.com/sar/vs-code-container-with-ssl.git 143 | 144 | # -------------- 145 | # CodeServer: Setup 146 | # -------------- 147 | RUN npm install --unsafe-perm -g code-server@${RELEASE_CODE_SERVER} 148 | 149 | # @diff upstream:: 150 | # @repo https://github.com/sar/neovim-container.git 151 | 152 | # -------------- 153 | # Podman: Runtime 154 | # -------------- 155 | 156 | # docker-compose 157 | USER root 158 | RUN wget https://download.docker.com/linux/debian/gpg -O docker.gpg && \ 159 | apt-key add docker.gpg && \ 160 | add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \ 161 | apt-get update && \ 162 | apt install -y \ 163 | docker-compose && \ 164 | apt remove -y golang-docker-credential-helpers 165 | 166 | # Podman 167 | RUN apt install -y podman 168 | 169 | # Podman Config 170 | RUN id $DEFAULT_USER && \ 171 | systemctl enable podman.socket 172 | 173 | # -------------- 174 | # SDK: Dotnet Core 175 | # -------------- 176 | RUN wget https://packages.microsoft.com/config/debian/$(lsb_release -rs)/packages-microsoft-prod.deb \ 177 | -O packages-microsoft-prod.deb && \ 178 | dpkg -i packages-microsoft-prod.deb && \ 179 | apt-get update && \ 180 | apt install -y \ 181 | dotnet-sdk-7.0 \ 182 | dotnet-runtime-7.0 \ 183 | dotnet-sdk-6.0 \ 184 | dotnet-runtime-6.0 \ 185 | dotnet-sdk-5.0 \ 186 | dotnet-runtime-5.0 \ 187 | dotnet-sdk-3.1 \ 188 | dotnet-runtime-3.1 \ 189 | dotnet-sdk-2.1 \ 190 | dotnet-runtime-2.1 191 | 192 | # dotnet-tools 193 | USER $DEFAULT_USER 194 | RUN dotnet tool install -g dotnet-ef && \ 195 | dotnet new --install Amazon.Lambda.Templates::${RELEASE_BIN_LAMBDA_DOTNET} && \ 196 | dotnet tool install -g Amazon.Lambda.Tools && \ 197 | dotnet tool install -g JetBrains.ReSharper.GlobalTools && \ 198 | ls -la $HOME/.dotnet/** 199 | 200 | USER root 201 | RUN cp /home/$DEFAULT_USER/.dotnet/tools/* /usr/local/sbin/ 202 | 203 | # netcoredbg 204 | USER $DEFAULT_USER 205 | RUN wget https://github.com/Samsung/netcoredbg/releases/download/${RELEASE_BIN_DOTNET_DBG}/netcoredbg-linux-amd64.tar.gz && \ 206 | tar -xzvf netcoredbg* && \ 207 | mv /tmp/netcoredbg/* /usr/local/sbin/ 208 | 209 | # -------------- 210 | # SDK: AWS CLI, aws-shell 211 | # -------------- 212 | USER root 213 | RUN wget "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -O "awscliv2.zip" && \ 214 | unzip awscliv2.zip && \ 215 | ./aws/install && \ 216 | pip3 install aws-shell --user 217 | 218 | RUN wget "https://github.com/aws-amplify/amplify-cli/releases/download/${RELEASE_BIN_AWS_AMPLIFY_CLI}/amplify-pkg-linux.tgz" && \ 219 | tar -xzvf amplify-pkg-linux.tgz && \ 220 | mv amplify-pkg-linux /usr/local/sbin/amplify 221 | 222 | # -------------- 223 | # SDK: Azure CLI 224 | # -------------- 225 | RUN curl -sL https://aka.ms/InstallAzureCLIDeb -o azure_cli.sh && \ 226 | chmod +x azure_cli.sh && \ 227 | ./azure_cli.sh 228 | 229 | # -------------- 230 | # NPM: Packages 231 | # -------------- 232 | USER root 233 | RUN npm install -g npm@${RELEASE_BIN_NPM} 234 | RUN npm install -g yarn 235 | 236 | RUN yarn global add \ 237 | webpack-cli \ 238 | create-react-app \ 239 | gatsby \ 240 | gulp \ 241 | @storybook/cli \ 242 | typescript-language-server 243 | 244 | # -------------- 245 | # PKG: Terraform 246 | # -------------- 247 | USER root 248 | RUN curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add - && \ 249 | apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main" && \ 250 | apt-get update && \ 251 | apt install -y terraform 252 | 253 | # build::source::github.com/sar/autosaved 254 | USER root 255 | WORKDIR /tmp 256 | RUN git clone https://github.com/sar/autosaved.git && \ 257 | cd autosaved && \ 258 | make && \ 259 | mv ./bin/autosaved_linux_amd64 /usr/local/sbin/autosaved && \ 260 | rm -rf /tmp/autosaved 261 | 262 | # -------------- 263 | # PKG: Binaries 264 | # TODO: build from source 265 | # -------------- 266 | WORKDIR /tmp 267 | 268 | # terraformer 269 | RUN wget https://github.com/GoogleCloudPlatform/terraformer/releases/download/${RELEASE_TERRAFORMER}/terraformer-all-linux-amd64 && \ 270 | mv terraformer-all-linux-amd64 /usr/local/sbin/terraformer 271 | 272 | # github act local 273 | USER root 274 | RUN wget https://raw.githubusercontent.com/nektos/act/master/install.sh -O act_install.sh && \ 275 | sha256sum act_install.sh && \ 276 | chmod +x ./act_install.sh && \ 277 | ./act_install.sh 278 | 279 | # gh cli 280 | RUN wget https://github.com/cli/cli/releases/download/v${RELEASE_BIN_GITHUB}/gh_${RELEASE_BIN_GITHUB}_linux_amd64.deb && \ 281 | dpkg -i gh*_amd64.deb && \ 282 | which gh 283 | 284 | # dive 285 | RUN wget https://github.com/wagoodman/dive/releases/download/v${RELEASE_BIN_DIVE}/dive_${RELEASE_BIN_DIVE}_linux_amd64.deb && \ 286 | sha256sum ./dive*.deb && \ 287 | dpkg -i ./dive*.deb && \ 288 | which dive 289 | 290 | # dapr 291 | RUN wget https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O dapr_install.sh && \ 292 | sha256sum dapr_install.sh && \ 293 | chmod +x ./dapr_install.sh && \ 294 | ./dapr_install.sh && \ 295 | which dapr 296 | 297 | # gitui 298 | USER root 299 | RUN wget https://github.com/extrawurst/gitui/releases/download/${RELEASE_BIN_GITUI}/gitui-linux-musl.tar.gz && \ 300 | tar -xzvf gitui-linux-musl.tar.gz && \ 301 | mv gitui /usr/local/sbin/ 302 | 303 | # verco 304 | RUN wget https://github.com/vamolessa/verco/releases/download/${RELEASE_BIN_VERCO}/verco-linux-x86_64 -O verco && \ 305 | mv verco /usr/local/sbin/ 306 | 307 | # stackoverflow 308 | RUN wget https://github.com/samtay/so/releases/download/v0.4.5/so-v0.4.5-x86_64-unknown-linux-gnu.tar.gz && \ 309 | tar -xzvf so-v0.4.5-x86_64-unknown-linux-gnu.tar.gz && \ 310 | ls -la so* && \ 311 | mv so /usr/local/sbin 312 | 313 | # -------------- 314 | # Database Tools 315 | # -------------- 316 | 317 | # postgresql 318 | USER root 319 | RUN apt install -y \ 320 | postgresql-client \ 321 | pspg 322 | 323 | # mongodb 324 | RUN yarn global add mngr 325 | 326 | # build::source::sc-im 327 | RUN apt-get install -y \ 328 | bison \ 329 | libncurses5-dev \ 330 | libncursesw5-dev \ 331 | libxml2-dev \ 332 | libzip-dev \ 333 | pkg-config 334 | 335 | WORKDIR /tmp 336 | RUN git clone https://github.com/jmcnamara/libxlsxwriter.git && \ 337 | cd libxlsxwriter && \ 338 | make && \ 339 | make install && \ 340 | ldconfig 341 | 342 | WORKDIR /tmp 343 | RUN git clone https://github.com/andmarti1424/sc-im.git && \ 344 | cd sc-im/src && \ 345 | make && \ 346 | make install && \ 347 | which sc-im 348 | 349 | USER $DEFAULT_USER 350 | RUN mkdir -p ~/.config/sc-im 351 | COPY config/scimrc /home/$DEFAULT_USER/.config/sc-im/scimrc 352 | 353 | # -------------- 354 | # Shell: ZSH 355 | # -------------- 356 | USER root 357 | RUN apt install -y zsh && \ 358 | chsh -s /bin/zsh 359 | 360 | USER $DEFAULT_USER 361 | WORKDIR /tmp 362 | RUN wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O install_zsh.sh && \ 363 | chmod +x ./install_zsh.sh && \ 364 | ZSH=~/.zsh && \ 365 | ./install_zsh.sh --unattended && \ 366 | cd ~/.oh-my-zsh/themes/ && \ 367 | git clone https://github.com/romkatv/powerlevel10k.git && \ 368 | cd ~/.oh-my-zsh/custom/plugins && \ 369 | git clone https://github.com/zsh-users/zsh-syntax-highlighting.git && \ 370 | git clone https://github.com/zsh-users/zsh-completions.git && \ 371 | git clone https://github.com/zsh-users/zsh-history-substring-search.git && \ 372 | git clone https://github.com/zsh-users/zsh-autosuggestions.git 373 | #git clone https://github.com/romkatv/gitstatus.git 374 | 375 | WORKDIR /tmp 376 | COPY config/.zshrc /home/$DEFAULT_USER/.zshrc 377 | 378 | # -------------- 379 | # MAINT: Hosts 380 | # -------------- 381 | USER root 382 | RUN wget https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn-social/hosts \ 383 | -O /etc/hosts 384 | 385 | # -------------- 386 | # MAINT: Cleanup 387 | # -------------- 388 | RUN apt clean all 389 | 390 | # -------------- 391 | # MAINT: alias rm 392 | # -------------- 393 | RUN mv /bin/rm /bin/rmrm && \ 394 | cp /bin/trash /bin/rm 395 | 396 | # -------------- 397 | # MAINT: PERMISSIONS 398 | # -------------- 399 | USER root 400 | RUN chown -R ${DEFAULT_USER} /home/${DEFAULT_USER}/.config && \ 401 | chown -R $DEFAULT_USER /usr/local/sbin && \ 402 | chmod +x /usr/local/sbin/* 403 | 404 | USER $DEFAULT_USER 405 | RUN mkdir -p ~/.config/gh && \ 406 | mkdir -p ~/.local/share/NuGet && \ 407 | chown -R ${DEFAULT_USER} ~/.local/share/NuGet && \ 408 | mkdir -p /tmp/NuGetScratch && \ 409 | chown -R $DEFAULT_USER:$DEFAULT_USER /tmp/NuGetScratch 410 | 411 | # @diff code-server:: 412 | # @repo https://github.com/sar/vs-code-container-with-ssl.git 413 | 414 | # -------------- 415 | # CONFIG PATHS 416 | # -------------- 417 | RUN mkdir /config /config/data /config/extensions 418 | COPY init.sh /config/init.sh 419 | 420 | # @diff upstream:: 421 | # @repo https://github.com/sar/neovim-container.git 422 | 423 | # -------------- 424 | # EXPOSE RUNTIME PORTS 425 | # -------------- 426 | EXPOSE 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 427 | EXPOSE 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 428 | 429 | # -------------- 430 | # ENTRYPOINT: Code Server 431 | # -------------- 432 | USER $DEFAULT_USER 433 | ENTRYPOINT [ "/config/init.sh" ]; 434 | 435 | --------------------------------------------------------------------------------