Sure!

Side note: Unfortunately VSCode devcontainers aren't open source and do not work with VSCodium. Upvote if you'd like VSCode devcontainers open sourced. [1] This example should still work with VSCode though. And the devcontainer CLI.

Also, Zed has some issues around Podman and SELinux with an open PR. [2] And unfortunately Podman Compose does not currently work with Flatpak Zed. [3]

In Zed to enable Podman, add the following to Zed 'settings.json':

  "use_podman": true
Then we're just mostly following the guide:

https://containers.dev/guide/dockerfile

Create '.devcontainer/devcontainer.json':

  {
    "name": "projectName",
    "runArgs": ["--name", "projectName"],
    "dockerComposeFile": "docker-compose.yml",
    "service": "devcontainer",
    "features": {
      "ghcr.io/devcontainers/features/nix:1": {
        "packages": "devenv"
      }
    },
    "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
    "onCreateCommand": "nix-env -iA nixpkgs.devenv",
    "postCreateCommand": "git config --global user.name \"${GIT_USER_NAME}\" && git config --global user.email \"${GIT_USER_EMAIL}\" && git config --global --add --bool push.autoSetupRemote true && echo 'eval \"$(devenv hook bash)\"' | tee -a ~/.bashrc"
  
    // If compose isn't needed use the following:
    // "image": "mcr.microsoft.com/devcontainers/base:debian",
    // "containerEnv": {
    //   "GIT_USER_NAME": "${localEnv:GIT_USER_NAME}",
    //   "GIT_USER_EMAIL": "${localEnv:GIT_USER_EMAIL}",
    //   "SSH_AUTH_SOCK": "/run/host-services/ssh-auth.sock",
    // },
    // "mounts": [
    //   "source=${localEnv:XDG_RUNTIME_DIR}/ssh-agent.socket,target=/run/host-services/ssh-auth.sock,type=bind",
    // ],
  }
Then create '.devcontainer/docker-compose.yml':

  name: projectName
  services:
    devcontainer:
      image: mcr.microsoft.com/devcontainers/base:debian
      command: sleep infinity
      userns_mode: keep-id
      environment:
        SSH_AUTH_SOCK: /run/host-services/ssh-auth.sock
        GIT_USER_EMAIL: ${GIT_USER_EMAIL?err}
        GIT_USER_NAME: ${GIT_USER_NAME?err}
        POSTGRES_DB: ${POSTGRES_DB:-projectName}
        POSTGRES_USER: ${POSTGRES_USER:-postgres}
        POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
      ports:
        # To connect to postgres running inside the container
        - target: 5432
          published: 5432
          protocol: tcp
          host_ip: 127.0.0.1
          mode: host
      volumes:
        - ${XDG_RUNTIME_DIR}/ssh-agent.socket:/run/host-services/ssh-auth.sock:bind
        - ..:/workspaces/projectName:cached
And lastly create 'devenv.nix':

  { pkgs, config, ... }: {
    env.GREET = "determinism";
  
    enterShell = ''
      echo hello ${config.env.GREET}
    '';
  
    packages = [
      pkgs.nodejs
      pkgs.yarn
    ];
  
    services = {
      postgres = {
        enable = true;
        listen_addresses = "0.0.0.0";
        hbaConf = ''
          # TYPE      DATABASE      USER      ADDRESS       METHOD
            local       all         all                     peer
            host        all         all       127.0.0.1/32  trust
            host        all         all       0.0.0.0/0     md5
        '';
        initialDatabases = [
          {
            name = "postgres";
          }
          {
            name = "projectName";
          }
          {
            name = "projectName_auth";
          }
        ];
        initialScript = ''
          CREATE ROLE postgres SUPERUSER LOGIN PASSWORD 'postgres';
          CREATE ROLE api LOGIN PASSWORD 'api';
          CREATE ROLE auth LOGIN PASSWORD 'auth';
        '';
        settings = {
          wal_level = "logical";
        };
      };
    };
  
    scripts = {
      drizzle.exec = "npx lerna run --scope @projectName/drizzle \"$@\"";
      better-auth.exec = "npx lerna run --scope @projectName/better-auth \"$@\"";
    };
  }
On Linux with SELinux, until the PR [2] is merged, a workaround for Zed needs to be applied:

  # ~/.config/containers/containers.conf
  [containers]
  label = false
After this you can work within a podman container, connect to adjacent compose services, and use nix and devenv. If a collaborator wants to skip containers they can just run devenv locally. Though I think devcontainers running devenv is actually the easier route provided that they are setup and working on your OS.

And this all works pretty much out of the box without root on an immutable OS like Fedora Silverblue/Kinoite.

---

[1](https://github.com/microsoft/vscode-remote-release/issues/11...)

[2](https://github.com/zed-industries/zed/pull/58500)

[3](https://github.com/flathub/dev.zed.Zed/pull/342#issuecomment...)