aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@outlook.com>2025-06-29 15:07:57 +0800
committerYuqian Yang <crupest@outlook.com>2025-06-29 15:08:47 +0800
commita123d4266935ff9d75a8e32dd29ee965e9eb4d50 (patch)
treeb5bc36630c747f1311b4e4f8f7b6fb489dd59640
parent50299600c0134f00c7f8e4fe6b599987596c6dc5 (diff)
downloadcrupest-a123d4266935ff9d75a8e32dd29ee965e9eb4d50.tar.gz
crupest-a123d4266935ff9d75a8e32dd29ee965e9eb4d50.tar.bz2
crupest-a123d4266935ff9d75a8e32dd29ee965e9eb4d50.zip
debian-dev: refactor all.
-rw-r--r--.editorconfig3
-rw-r--r--services/docker/debian-dev/Dockerfile24
-rwxr-xr-xservices/docker/debian-dev/bootstrap/extra/setup-cmake.bash9
-rwxr-xr-xservices/docker/debian-dev/bootstrap/extra/setup-dotnet.bash10
-rwxr-xr-xservices/docker/debian-dev/bootstrap/extra/setup-llvm.bash26
-rw-r--r--services/docker/debian-dev/bootstrap/home/.bashrc117
-rw-r--r--services/docker/debian-dev/bootstrap/official.sources23
-rwxr-xr-xservices/docker/debian-dev/bootstrap/setup-apt.bash41
-rwxr-xr-xservices/docker/debian-dev/bootstrap/setup.bash56
-rw-r--r--services/templates/disabled/docker-compose.yaml21
-rw-r--r--services/templates/disabled/nginx/code.conf.template20
-rw-r--r--store/debian-dev/Dockerfile20
-rwxr-xr-xstore/debian-dev/setup/apt.bash33
-rw-r--r--store/debian-dev/setup/bashrc3
-rwxr-xr-xstore/debian-dev/setup/cmake.bash9
-rwxr-xr-xstore/debian-dev/setup/code-server.bash17
-rwxr-xr-xstore/debian-dev/setup/for-container.bash14
-rwxr-xr-xstore/debian-dev/setup/llvm.bash11
-rwxr-xr-xstore/debian-dev/setup/package.bash10
-rw-r--r--store/debian-dev/setup/quiltrc-dpkg (renamed from services/docker/debian-dev/bootstrap/home/.quiltrc-dpkg)0
-rwxr-xr-xstore/debian-dev/setup/user.bash11
21 files changed, 131 insertions, 347 deletions
diff --git a/.editorconfig b/.editorconfig
index 69ce65e..92ff780 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -18,6 +18,9 @@ max_line_length = 80
[*.{sh,bash}]
indent_size = 2
+[store/debian-dev/**/*.{sh,bash}]
+indent_size = 4
+
[*.{html,css,js,ts}]
indent_size = 2
diff --git a/services/docker/debian-dev/Dockerfile b/services/docker/debian-dev/Dockerfile
deleted file mode 100644
index 8114c56..0000000
--- a/services/docker/debian-dev/Dockerfile
+++ /dev/null
@@ -1,24 +0,0 @@
-FROM debian:latest
-
-ARG USER=crupest
-ARG IN_CHINA=
-
-ENV CRUPEST_DEBIAN_DEV_USER=${USER}
-ENV CRUPEST_DEBIAN_DEV_IN_CHINA=${IN_CHINA}
-
-ADD bootstrap /bootstrap
-RUN /bootstrap/setup.bash
-
-ENV LANG=en_US.utf8
-USER ${USER}
-WORKDIR /home/${USER}
-
-RUN --mount=type=secret,id=code-server-password,required=true,env=CRUPEST_CODE_SERVER_PASSWORD \
- mkdir -p ${HOME}/.config/code-server && \
- echo -e "auth: password\nhashed-password: " >> ${HOME}/.config/code-server/config.yaml && \
- echo -n "$CRUPEST_CODE_SERVER_PASSWORD" | argon2 $(shuf -i 10000000-99999999 -n 1 --random-source /dev/urandom) -e >> ${HOME}/.config/code-server/config.yaml
-
-EXPOSE 4567
-VOLUME [ "/home/${USER}" ]
-
-CMD [ "tini", "--", "/usr/bin/code-server", "--bind-addr", "0.0.0.0:4567" ]
diff --git a/services/docker/debian-dev/bootstrap/extra/setup-cmake.bash b/services/docker/debian-dev/bootstrap/extra/setup-cmake.bash
deleted file mode 100755
index 76c1ae4..0000000
--- a/services/docker/debian-dev/bootstrap/extra/setup-cmake.bash
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /usr/bin/env bash
-
-set -e
-
-CMAKE_VERSION=$(curl -s https://api.github.com/repos/Kitware/CMake/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
-wget -O cmake-installer.sh https://github.com/Kitware/CMake/releases/download/v"$CMAKE_VERSION"/cmake-"$CMAKE_VERSION"-linux-x86_64.sh
-chmod +x cmake-installer.sh
-./cmake-installer.sh --skip-license --prefix=/usr
-rm cmake-installer.sh
diff --git a/services/docker/debian-dev/bootstrap/extra/setup-dotnet.bash b/services/docker/debian-dev/bootstrap/extra/setup-dotnet.bash
deleted file mode 100755
index 0ef7743..0000000
--- a/services/docker/debian-dev/bootstrap/extra/setup-dotnet.bash
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /usr/bin/env bash
-
-set -e
-
-wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
-dpkg -i packages-microsoft-prod.deb
-rm packages-microsoft-prod.deb
-
-apt-get update
-apt-get install -y dotnet-sdk-7.0
diff --git a/services/docker/debian-dev/bootstrap/extra/setup-llvm.bash b/services/docker/debian-dev/bootstrap/extra/setup-llvm.bash
deleted file mode 100755
index 48dde86..0000000
--- a/services/docker/debian-dev/bootstrap/extra/setup-llvm.bash
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /usr/bin/env bash
-
-set -e
-
-LLVM_VERSION=18
-
-. /bootstrap/func.bash
-
-if is_true "$CRUPEST_DEBIAN_DEV_IN_CHINA"; then
- base_url=https://mirrors.tuna.tsinghua.edu.cn/llvm-apt
-else
- base_url=https://apt.llvm.org
-fi
-
-wget "$base_url/llvm.sh"
-chmod +x llvm.sh
-./llvm.sh $LLVM_VERSION all -m "$base_url"
-rm llvm.sh
-
-update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$LLVM_VERSION 100 \
- --slave /usr/bin/clang++ clang++ /usr/bin/clang++-$LLVM_VERSION \
- --slave /usr/bin/clangd clangd /usr/bin/clangd-$LLVM_VERSION \
- --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-$LLVM_VERSION \
- --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-$LLVM_VERSION \
- --slave /usr/bin/lldb lldb /usr/bin/lldb-$LLVM_VERSION \
- --slave /usr/bin/lld lld /usr/bin/lld-$LLVM_VERSION
diff --git a/services/docker/debian-dev/bootstrap/home/.bashrc b/services/docker/debian-dev/bootstrap/home/.bashrc
deleted file mode 100644
index 3646ee2..0000000
--- a/services/docker/debian-dev/bootstrap/home/.bashrc
+++ /dev/null
@@ -1,117 +0,0 @@
-# ~/.bashrc: executed by bash(1) for non-login shells.
-# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
-# for examples
-
-# If not running interactively, don't do anything
-case $- in
- *i*) ;;
- *) return;;
-esac
-
-# don't put duplicate lines or lines starting with space in the history.
-# See bash(1) for more options
-HISTCONTROL=ignoreboth
-
-# append to the history file, don't overwrite it
-shopt -s histappend
-
-# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
-HISTSIZE=1000
-HISTFILESIZE=2000
-
-# check the window size after each command and, if necessary,
-# update the values of LINES and COLUMNS.
-shopt -s checkwinsize
-
-# If set, the pattern "**" used in a pathname expansion context will
-# match all files and zero or more directories and subdirectories.
-#shopt -s globstar
-
-# make less more friendly for non-text input files, see lesspipe(1)
-#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
-
-# set variable identifying the chroot you work in (used in the prompt below)
-if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
- debian_chroot=$(cat /etc/debian_chroot)
-fi
-
-# set a fancy prompt (non-color, unless we know we "want" color)
-case "$TERM" in
- xterm-color|*-256color) color_prompt=yes;;
-esac
-
-# uncomment for a colored prompt, if the terminal has the capability; turned
-# off by default to not distract the user: the focus in a terminal window
-# should be on the output of commands, not on the prompt
-#force_color_prompt=yes
-
-if [ -n "$force_color_prompt" ]; then
- if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
- # We have color support; assume it's compliant with Ecma-48
- # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
- # a case would tend to support setf rather than setaf.)
- color_prompt=yes
- else
- color_prompt=
- fi
-fi
-
-if [ "$color_prompt" = yes ]; then
- PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
-else
- PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
-fi
-unset color_prompt force_color_prompt
-
-# If this is an xterm set the title to user@host:dir
-case "$TERM" in
-xterm*|rxvt*)
- PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
- ;;
-*)
- ;;
-esac
-
-# enable color support of ls and also add handy aliases
-if [ -x /usr/bin/dircolors ]; then
- test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
- alias ls='ls --color=auto'
- #alias dir='dir --color=auto'
- #alias vdir='vdir --color=auto'
-
- #alias grep='grep --color=auto'
- #alias fgrep='fgrep --color=auto'
- #alias egrep='egrep --color=auto'
-fi
-
-# colored GCC warnings and errors
-#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
-
-# some more ls aliases
-#alias ll='ls -l'
-#alias la='ls -A'
-#alias l='ls -CF'
-
-# Alias definitions.
-# You may want to put all your additions into a separate file like
-# ~/.bash_aliases, instead of adding them here directly.
-# See /usr/share/doc/bash-doc/examples in the bash-doc package.
-
-if [ -f ~/.bash_aliases ]; then
- . ~/.bash_aliases
-fi
-
-# enable programmable completion features (you don't need to enable
-# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
-# sources /etc/bash.bashrc).
-if ! shopt -oq posix; then
- if [ -f /usr/share/bash-completion/bash_completion ]; then
- . /usr/share/bash-completion/bash_completion
- elif [ -f /etc/bash_completion ]; then
- . /etc/bash_completion
- fi
-fi
-
-alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg"
-. /usr/share/bash-completion/completions/quilt
-complete -F _quilt_completion $_quilt_complete_opt dquilt
diff --git a/services/docker/debian-dev/bootstrap/official.sources b/services/docker/debian-dev/bootstrap/official.sources
deleted file mode 100644
index c9aa9a0..0000000
--- a/services/docker/debian-dev/bootstrap/official.sources
+++ /dev/null
@@ -1,23 +0,0 @@
-Types: deb
-URIs: http://deb.debian.org/debian
-Suites: bookworm bookworm-updates bookworm-backports
-Components: main contrib non-free non-free-firmware
-Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
-
-Types: deb-src
-URIs: http://deb.debian.org/debian
-Suites: bookworm bookworm-updates bookworm-backports
-Components: main contrib non-free non-free-firmware
-Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
-
-Types: deb
-URIs: http://deb.debian.org/debian-security
-Suites: bookworm-security
-Components: main contrib non-free non-free-firmware
-Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
-
-Types: deb-src
-URIs: http://deb.debian.org/debian-security
-Suites: bookworm-security
-Components: main contrib non-free non-free-firmware
-Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
diff --git a/services/docker/debian-dev/bootstrap/setup-apt.bash b/services/docker/debian-dev/bootstrap/setup-apt.bash
deleted file mode 100755
index 38cba05..0000000
--- a/services/docker/debian-dev/bootstrap/setup-apt.bash
+++ /dev/null
@@ -1,41 +0,0 @@
-#! /usr/bin/env bash
-# shellcheck disable=1090,1091
-
-set -e
-
-if [[ $EUID -ne 0 ]]; then
- die "This script must be run as root."
-fi
-
-script_dir=$(dirname "$0")
-
-old_one="/etc/apt/sources.list"
-new_one="/etc/apt/sources.list.d/debian.sources"
-
-echo "Setup apt sources ..."
-
-echo "Backup old ones to .bak ..."
-if [[ -f "$old_one" ]]; then
- mv "$old_one" "$old_one.bak"
-fi
-
-if [[ -f "$new_one" ]]; then
- mv "$new_one" "$new_one.bak"
-fi
-
-echo "Copy the new one ..."
-cp "$script_dir/official.sources" "$new_one"
-
-if [[ -n "$CRUPEST_DEBIAN_DEV_IN_CHINA" ]]; then
- echo "Replace with China mirror ..."
- china_mirror="mirrors.ustc.edu.cn"
- sed -i "s|deb.debian.org|${china_mirror}|" "$new_one"
-fi
-
-echo "Try to use https ..."
-apt-get update
-apt-get install -y apt-transport-https ca-certificates
-
-sed -i 's|http://|https://|' "$new_one"
-
-echo "APT source setup done!"
diff --git a/services/docker/debian-dev/bootstrap/setup.bash b/services/docker/debian-dev/bootstrap/setup.bash
deleted file mode 100755
index 65aabbb..0000000
--- a/services/docker/debian-dev/bootstrap/setup.bash
+++ /dev/null
@@ -1,56 +0,0 @@
-#! /usr/bin/env bash
-# shellcheck disable=1090,1091
-
-set -e -o pipefail
-
-die() {
- echo "$@" >&2
- exit 1
-}
-
-if [[ $EUID -ne 0 ]]; then
- die "This script must be run as root."
-fi
-
-script_dir=$(dirname "$0")
-
-os_release_file="/etc/os-release"
-if [[ -f "$os_release_file" ]]; then
- debian_version=$(. "$os_release_file"; echo "$VERSION_CODENAME")
- if [[ "$debian_version" != "bookworm" ]]; then
- die "This script can only be run on Debian Bookworm. But it is $debian_version"
- fi
-else
- die "$os_release_file not found. Failed to get debian version."
-fi
-
-script_dir=$(dirname "$0")
-
-export DEBIAN_FRONTEND=noninteractive
-
-echo "Begin to setup debian..."
-
-bash "$script_dir/setup-apt.bash"
-
-echo "Installing packages..."
-apt-get update
-apt-get install -y \
- tini locales procps sudo vim less man bash-completion curl wget \
- build-essential git devscripts debhelper quilt argon2
-
-echo "Setting up locale..."
-localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
-
-echo "Setting up sudo..."
-sed -i.bak 's|%sudo[[:space:]]\+ALL=(ALL:ALL)[[:space:]]\+ALL|%sudo ALL=(ALL:ALL) NOPASSWD: ALL|' /etc/sudoers
-
-echo "Creating user $CRUPEST_DEBIAN_DEV_USER ..."
-useradd -m -G sudo -s /usr/bin/bash "$CRUPEST_DEBIAN_DEV_USER"
-
-echo "Setting up code-server..."
-curl -fsSL https://code-server.dev/install.sh | sh
-
-echo "Cleaning up apt source index..."
-rm -rf /var/lib/apt/lists/*
-
-echo "Setup debian done."
diff --git a/services/templates/disabled/docker-compose.yaml b/services/templates/disabled/docker-compose.yaml
index 565ca49..0cd2256 100644
--- a/services/templates/disabled/docker-compose.yaml
+++ b/services/templates/disabled/docker-compose.yaml
@@ -1,22 +1,4 @@
services:
- debian-dev:
- pull_policy: build
- build:
- context: ./docker/debian-dev
- dockerfile: Dockerfile
- pull: true
- args:
- - USER=crupest
- tags:
- - "crupest/debian-dev:latest"
- container_name: debian-dev
- init: true
- command: [ "/bootstrap/start/code-server.bash" ]
- volumes:
- - ./data/debian-dev:/data
- - debian-dev-home:/home/crupest
- restart: on-failure:3
-
timeline:
image: crupest/timeline:latest
pull_policy: always
@@ -27,6 +9,3 @@ services:
- TIMELINE_DisableAutoBackup=true
volumes:
- ./data/timeline:/root/timeline
-
-volumes:
- debian-dev-home:
diff --git a/services/templates/disabled/nginx/code.conf.template b/services/templates/disabled/nginx/code.conf.template
deleted file mode 100644
index 0abe042..0000000
--- a/services/templates/disabled/nginx/code.conf.template
+++ /dev/null
@@ -1,20 +0,0 @@
-server {
- server_name code.@@CRUPEST_DOMAIN@@;
- include common/https-listen;
-
- location / {
- include common/proxy-common;
- proxy_pass http://debian-dev:8080/;
- }
-
- client_max_body_size 5G;
-}
-
-
-server {
- server_name code.@@CRUPEST_DOMAIN@@;
- include common/http-listen;
-
- include common/https-redirect;
- include common/acme-challenge;
-}
diff --git a/store/debian-dev/Dockerfile b/store/debian-dev/Dockerfile
new file mode 100644
index 0000000..732ffa4
--- /dev/null
+++ b/store/debian-dev/Dockerfile
@@ -0,0 +1,20 @@
+ARG VERSION=latest
+FROM debian:${VERSION}
+
+ARG USER=
+ARG CHINA=
+
+ENV CRUPEST_DEBIAN_DEV_USER=${USER}
+ENV CRUPEST_DEBIAN_DEV_CHINA=${CHINA}
+
+ADD setup /setup
+RUN env DEBIAN_FRONTEND=noninteractive /setup/apt.bash
+RUN env DEBIAN_FRONTEND=noninteractive /setup/package.bash
+RUN env DEBIAN_FRONTEND=noninteractive /setup/for-container.bash
+
+ENV LANG=en_US.utf8
+USER ${USER}
+WORKDIR /home/${USER}
+RUN env DEBIAN_FRONTEND=noninteractive /setup/user.bash
+
+VOLUME [ "/home/${USER}" ]
diff --git a/store/debian-dev/setup/apt.bash b/store/debian-dev/setup/apt.bash
new file mode 100755
index 0000000..e841351
--- /dev/null
+++ b/store/debian-dev/setup/apt.bash
@@ -0,0 +1,33 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+china_mirror="mirrors.ustc.edu.cn"
+try_files=("/etc/apt/sources.list" "/etc/apt/sources.list.d/debian.sources")
+files=()
+
+for try_file in "${try_files[@]}"; do
+ if [[ -f "$try_file" ]]; then
+ files+=("$try_file")
+ fi
+done
+
+for file in "${files[@]}"; do
+ echo "copy $file to $file.bak"
+ cp "$file" "$file.bak"
+done
+
+if [[ -n "$CRUPEST_DEBIAN_DEV_CHINA" ]]; then
+ echo "use China mirrors"
+ for file in "${files[@]}"; do
+ sed -i "s|deb.debian.org|${china_mirror}|g" "$file"
+ done
+fi
+
+echo "use https"
+apt-get update
+apt-get install -y apt-transport-https ca-certificates
+
+for file in "${files[@]}"; do
+ sed -i 's|http://|https://|g' "$file"
+done
diff --git a/store/debian-dev/setup/bashrc b/store/debian-dev/setup/bashrc
new file mode 100644
index 0000000..00c9d11
--- /dev/null
+++ b/store/debian-dev/setup/bashrc
@@ -0,0 +1,3 @@
+alias dquilt='quilt "--quiltrc=${HOME}/.quiltrc-dpkg"'
+. /usr/share/bash-completion/completions/quilt
+complete -F _quilt_completion $_quilt_complete_opt dquilt
diff --git a/store/debian-dev/setup/cmake.bash b/store/debian-dev/setup/cmake.bash
new file mode 100755
index 0000000..dd7307e
--- /dev/null
+++ b/store/debian-dev/setup/cmake.bash
@@ -0,0 +1,9 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+CMAKE_VERSION=$(curl -s https://api.github.com/repos/Kitware/CMake/releases/latest | \
+ grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
+
+curl -fsSL "https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-linux-x86_64.sh" | \
+ sh -s -- --skip-license --prefix=/usr
diff --git a/store/debian-dev/setup/code-server.bash b/store/debian-dev/setup/code-server.bash
new file mode 100755
index 0000000..1151dc2
--- /dev/null
+++ b/store/debian-dev/setup/code-server.bash
@@ -0,0 +1,17 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+if [[ $# != 1 ]]; then
+ echo "Require exactly one argument, the password of the code server." >&2
+ exit 1
+fi
+
+curl -fsSL https://code-server.dev/install.sh | sh
+
+apt update && apt install argon2
+mkdir -p "${HOME}/.config/code-server"
+echo -e "auth: password\nhashed-password: " >> "${HOME}/.config/code-server/config.yaml"
+echo -n "$1" | \
+ argon2 "$(shuf -i 10000000-99999999 -n 1 --random-source /dev/urandom)" -e \
+ >> "${HOME}/.config/code-server/config.yaml"
diff --git a/store/debian-dev/setup/for-container.bash b/store/debian-dev/setup/for-container.bash
new file mode 100755
index 0000000..0aa47b0
--- /dev/null
+++ b/store/debian-dev/setup/for-container.bash
@@ -0,0 +1,14 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+echo "set up locale"
+localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
+
+echo "set up sudo"
+sed -i.bak 's|%sudo[[:space:]]\+ALL=(ALL:ALL)[[:space:]]\+ALL|%sudo ALL=(ALL:ALL) NOPASSWD: ALL|' /etc/sudoers
+
+if ! id "username" &>/dev/null; then
+ echo "create user $CRUPEST_DEBIAN_DEV_USER"
+ useradd -m -G sudo -s /usr/bin/bash "$CRUPEST_DEBIAN_DEV_USER"
+fi
diff --git a/store/debian-dev/setup/llvm.bash b/store/debian-dev/setup/llvm.bash
new file mode 100755
index 0000000..ca6d4bf
--- /dev/null
+++ b/store/debian-dev/setup/llvm.bash
@@ -0,0 +1,11 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+if [[ -n "$CRUPEST_DEBIAN_DEV_CHINA" ]]; then
+ base_url=https://mirrors.tuna.tsinghua.edu.cn/llvm-apt
+else
+ base_url=https://apt.llvm.org
+fi
+
+curl -fsSL "$base_url/llvm.sh" | sh -s -- all -m "$base_url"
diff --git a/store/debian-dev/setup/package.bash b/store/debian-dev/setup/package.bash
new file mode 100755
index 0000000..5ad7b7a
--- /dev/null
+++ b/store/debian-dev/setup/package.bash
@@ -0,0 +1,10 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+echo "install packages"
+apt-get update
+apt-get install -y \
+ locales lsb-release software-properties-common \
+ sudo procps bash-completion man less gnupg curl wget \
+ vim build-essential git devscripts debhelper quilt
diff --git a/services/docker/debian-dev/bootstrap/home/.quiltrc-dpkg b/store/debian-dev/setup/quiltrc-dpkg
index e8fc3c5..e8fc3c5 100644
--- a/services/docker/debian-dev/bootstrap/home/.quiltrc-dpkg
+++ b/store/debian-dev/setup/quiltrc-dpkg
diff --git a/store/debian-dev/setup/user.bash b/store/debian-dev/setup/user.bash
new file mode 100755
index 0000000..4e13804
--- /dev/null
+++ b/store/debian-dev/setup/user.bash
@@ -0,0 +1,11 @@
+#! /usr/bin/env bash
+
+set -e -o pipefail
+
+base_dir="$(dirname "$0")"
+dot_files=("bashrc" "quiltrc-dpkg")
+
+for file in "${dot_files[@]}"; do
+ echo "copy $base_dir/$file $HOME/.$file"
+ cp "$base_dir/$file" "$HOME/.$file"
+done