Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a Docker environment that can host the current nix environment. #2016

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.205.1/containers/typescript-node
{
"name": "Node.js & TypeScript",
"build": {
"dockerfile": "../docker-dev-env/Dockerfile",
// Update 'VARIANT' to pick a Node version: 16, 14, 12.
// Append -bullseye or -buster to pin to an OS version.
// Use -bullseye variants on local on arm64/Apple Silicon.
"args": {
"VARIANT": "16-bullseye",
}
},

// Set *default* container specific settings.json values on container create.
"settings": {},


// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"dbaeumer.vscode-eslint"
],

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

"initializeCommand": "cp ./shell.nix docker-dev-env/ && cp ./release.nix docker-dev-env/",

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "sudo bash -c 'nix-daemon &' && echo 'eval \"$(direnv hook bash)\"' > ~/.bashrc && echo \"use nix\" > .envrc && direnv allow",

// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
"features": {
"git": "os-provided",
}
}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,8 @@ utopia-db

# Nix builds.
server-build-result

# Docker Dev Environment
docker-dev-env/*.nix
docker-dev-env/.cache
.pnpm-store
62 changes: 62 additions & 0 deletions docker-dev-env/.direnvrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use_nix() {
local path="$(nix-instantiate --find-file nixpkgs)"

if [ -f "${path}/.version-suffix" ]; then
local version="$(< $path/.version-suffix)"
elif [ -f "${path}/.git" ]; then
local version="$(< $(< ${path}/.git/HEAD))"
fi

local cache=".direnv/cache-${version:-unknown}"

local update_drv=0
if [[ ! -e "$cache" ]] || \
[[ "$HOME/.direnvrc" -nt "$cache" ]] || \
[[ .envrc -nt "$cache" ]] || \
[[ default.nix -nt "$cache" ]] || \
[[ shell.nix -nt "$cache" ]];
then
[ -d .direnv ] || mkdir .direnv
sudo nix-shell --show-trace --pure "$@" --run "\"$direnv\" dump bash" > "$cache"
update_drv=1
else
log_status using cached derivation
fi
local term_backup=$TERM path_backup=$PATH home_backup=$HOME
if [ -n ${TMPDIR+x} ]; then
local tmp_backup=$TMPDIR
fi

eval "$(< $cache)"
export PATH=$PATH:$path_backup TERM=$term_backup TMPDIR=$tmp_backup HOME=$home_backup
if [ -n ${tmp_backup+x} ]; then
export TMPDIR=${tmp_backup}
else
unset TMPDIR
fi

# `nix-shell --pure` sets invalid ssl certificate paths
if [ "${SSL_CERT_FILE:-}" = /no-cert-file.crt ]; then
unset SSL_CERT_FILE
fi
if [ "${NIX_SSL_CERT_FILE:-}" = /no-cert-file.crt ]; then
unset NIX_SSL_CERT_FILE
fi

# This part is based on https://discourse.nixos.org/t/what-is-the-best-dev-workflow-around-nix-shell/418/4
if [ "$out" ] && (( $update_drv )); then
local drv_link=".direnv/drv"
local drv="$(nix show-derivation $out | grep -E -o -m1 '/nix/store/.*.drv')"
local stripped_pwd=${PWD/\//}
local escaped_pwd=${stripped_pwd//-/--}
local escaped_pwd=${escaped_pwd//\//-}
ln -fs "$drv" "$drv_link"
ln -fs "$PWD/$drv_link" "/nix/var/nix/gcroots/per-user/$LOGNAME/$escaped_pwd"
log_status renewed cache and derivation link
fi

if [[ $# = 0 ]]; then
watch_file default.nix
watch_file shell.nix
fi
}
1 change: 1 addition & 0 deletions docker-dev-env/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.cache
44 changes: 44 additions & 0 deletions docker-dev-env/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM mcr.microsoft.com/vscode/devcontainers/base:hirsute

# RUN set -ex && apk --no-cache add sudo chromium
RUN apt-get update
RUN apt-get install --no-install-recommends -y nix-bin


# I commented this out && sudo chown $DOCKER_USER /nix
RUN sudo mkdir -m 0755 /nix && sudo mkdir -p /etc/nix && sudo groupadd -r nixbld \
&& for n in $(seq 1 10); do sudo useradd -c "Nix build user $n" -d /var/empty -g nixbld -G nixbld -M -N -r -s "$(command -v nologin)" "nixbld$n"; done

RUN echo 'filter-syscalls = false' >> /etc/nix/nix.conf
RUN nix-channel --add https://nixos.org/channels/nixos-21.05 nixpkgs
RUN nix-channel --update

# Attempt to get the nix dependencies of the shell cached into a Docker layer.
RUN mkdir -p /root/.nix-tmp
WORKDIR /root/.nix-tmp
ADD shell.nix /root/.nix-tmp/shell.nix
ADD release.nix /root/.nix-tmp/release.nix
RUN nix-shell --run "exit"

EXPOSE 8000

RUN chmod -R o+rwx /root/

RUN mkdir -p /root/.cabal/
VOLUME /root/.cabal/

# This is for jest.
ENV CHROME_BIN=chromium-browser

RUN apt-get install --no-install-recommends -y locales
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
RUN locale-gen en_US.UTF-8
RUN dpkg-reconfigure locales
# RUN update-locale LANG='en_US.UTF-8'

# install Direnv for the vscodeuser user
RUN apt-get install --no-install-recommends -y direnv
ADD .direnvrc /home/vscode/.direnvrc

RUN echo 'export TMPDIR=/tmp' > ~/.bashrc
RUN echo 'export TMPDIR=/tmp' > /home/$DOCKER_USER/.bashrc
36 changes: 36 additions & 0 deletions run-docker-dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -e

PROJECT_ROOT=`git rev-parse --show-toplevel`
DOCKER_DEV_ENV_DIR=$PROJECT_ROOT/docker-dev-env
DOCKER_CACHE_DIR=$DOCKER_DEV_ENV_DIR/.cache
CABAL_CACHE_DIR=$DOCKER_CACHE_DIR/.cabal
DOCKER_USER=`whoami`
DOCKER_UID=`id -u`

# Create the cache directories that Docker can use between sessions.
mkdir -p $CABAL_CACHE_DIR

# Copy the nix files into here so they can be used inside the Dockerfile.
cp $PROJECT_ROOT/shell.nix $DOCKER_DEV_ENV_DIR
cp $PROJECT_ROOT/release.nix $DOCKER_DEV_ENV_DIR

echo $DOCKER_DEV_ENV_DIR
echo $DOCKER_USER

# Build the Docker image.
docker build \
--tag utopia-dev-env \
--build-arg DOCKER_USER=$DOCKER_USER \
--build-arg DOCKER_UID=$DOCKER_UID \
$DOCKER_DEV_ENV_DIR

# Run a shell within the Docker image produced.
docker run \
--interactive \
--tty \
--publish 8000:8000 \
--volume $PROJECT_ROOT:/home/utopia/utopia-src \
--volume $CABAL_CACHE_DIR:/root/.cabal \
utopia-dev-env \
nix-shell --run "sudo --preserve-env --user $DOCKER_USER bash"
2 changes: 1 addition & 1 deletion shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ let

scripts = withCustomDevScripts; # ++ (if needsRelease then releaseScripts else []);

linuxOnlyPackages = lib.optionals stdenv.isLinux [ pkgs.xvfb_run pkgs.x11 pkgs.xorg.libxkbfile ];
linuxOnlyPackages = lib.optionals stdenv.isLinux [ pkgs.xvfb_run pkgs.x11 pkgs.xorg.libX11 pkgs.xorg.libxkbfile ];
macOSOnlyPackages = lib.optionals stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [
Cocoa
CoreServices
Expand Down