If jq is missing from your dev container, you can install it and make it persist by adding it to the container’s Dockerfile or using a lifecycle script in your devcontainer.json. The exact steps depend on your base image and package manager, but the key is to install it during the image build or post-create phase, not just in a running shell. This article explains the background, the methods, and common pitfalls so you can get jq available every time you rebuild.
Why jq Goes Missing in Dev Containers
Dev containers are ephemeral by design. When you rebuild a container, the filesystem resets to the state defined by the image and the devcontainer.json configuration. Anything you install manually with apt, apk, or dnf inside a running container is lost on rebuild. This is a common source of confusion because it feels like the container should “remember” what you did, but it doesn’t unless you explicitly encode it.
Another reason jq might be missing is that the base image you chose (e.g., mcr.microsoft.com/devcontainers/base:ubuntu or node:20) does not include jq by default. Many official images strip out non-essential tools to keep the image small. You need to add it yourself.
How to Install jq and Make It Persistent
There are two main approaches: modify the Dockerfile (if you use one) or use the postCreateCommand in devcontainer.json. The Dockerfile approach is the most reliable because it runs during the image build, so the installed package is baked into the image layer. The lifecycle script approach runs after the container is created, but it still runs on every rebuild, so the package will be present.
Here are the steps for the most common scenarios:
- Ubuntu/Debian (apt): Add
RUN apt-get update && apt-get install -y jqto your Dockerfile, or use"postCreateCommand": "apt-get update && apt-get install -y jq"in devcontainer.json. - Alpine (apk): Add
RUN apk add --no-cache jqto your Dockerfile, or use"postCreateCommand": "apk add --no-cache jq". - CentOS/RHEL/Fedora (dnf/yum): Add
RUN dnf install -y jq(oryum) to your Dockerfile, or use the corresponding command in postCreateCommand.
If you are using a devcontainer.json without a Dockerfile, the postCreateCommand is the simplest way. It runs every time the container is created, so it will reinstall jq after each rebuild. However, if you use the postStartCommand instead, it runs every time you start the container (even if it wasn’t rebuilt), which is unnecessary but also works.
Choosing Between Dockerfile and Lifecycle Scripts
Which method you choose depends on your workflow:
- Dockerfile: Best if you already have a Dockerfile or want to share the image with others. It’s the most reproducible because the package is part of the image. You can also combine it with other setup steps like copying config files.
- postCreateCommand: Best for quick tweaks without rebuilding the image. It’s easier to read and modify, but it runs every time the container is created, which can slow down startup if you have many commands.
- postStartCommand: Use this only if you need jq to be installed every time the container starts, even if it wasn’t rebuilt. This is rare; usually postCreate is enough.
A common pattern is to use a Dockerfile for the base setup and a postCreateCommand for project-specific tools. For jq specifically, either works, but the Dockerfile is more robust because it doesn’t depend on network access during the post-create phase (though most dev containers have network).
Common Problems and How to Fix Them
Even after following the steps, you might run into issues:
- Command not found after install: This usually means the package manager didn’t install it where your shell looks. Check the PATH. On most systems, jq installs to
/usr/bin/jq, which is in the default PATH. If you installed it to a custom location, add it to PATH. - Permission denied: If you get a permission error during install, you might need to run the command with
sudo. In a dev container, you often run as root, but if not, usesudo. - Package not found: If your package manager can’t find jq, update the package list first. For apt, run
apt-get updatebeforeinstall. For apk, useapk update. - postCreateCommand not running: Make sure you placed it in the correct section of devcontainer.json. It should be at the top level, not inside
buildorrunArgs. Also, check the logs in VS Code (Output panel -> Dev Containers) to see any errors. - Rebuild not picking up changes: If you modified the Dockerfile, you need to rebuild the container with “Rebuild Container” (not just restart). In VS Code, use the command palette and select “Dev Containers: Rebuild Container”.
Alternative: Use a Base Image That Includes jq
Some dev container images come with jq pre-installed. For example, many of the official Microsoft dev container images (like mcr.microsoft.com/devcontainers/base:ubuntu) include jq as part of their standard tools. If you are using a custom image, check its documentation or inspect the image to see if jq is already there. If not, you can switch to an image that includes it, but that might be overkill if you only need jq for one project.
Another alternative is to use a multi-stage build in your Dockerfile to copy jq from a smaller image, but that’s more complex. For most users, installing via the package manager is the simplest.
How to Verify jq Is Installed
After you’ve added the install command, rebuild the container and run jq --version in the terminal. You should see output like jq-1.7.1. If you get a “command not found” error, check the installation logs and PATH. You can also run which jq to see the full path.
To test that it works, you can pipe some JSON to it: echo '{"key":"value"}' | jq '.key' should output "value". This confirms not only that jq is installed but also that it’s in your PATH.
Frequently Asked Questions
Why does jq disappear after I rebuild the container?
Because dev containers are ephemeral. The filesystem resets to the image state on rebuild. Anything you install manually in a running container is lost unless you add it to the Dockerfile or a lifecycle script.
What is the difference between postCreateCommand and postStartCommand?
postCreateCommand runs only when the container is created (i.e., after a rebuild). postStartCommand runs every time the container starts, even if it wasn’t rebuilt. For installing jq, postCreateCommand is usually sufficient because the container is created when you rebuild.
Can I install jq using a package manager other than apt?
Yes, it depends on your base image. Alpine uses apk, CentOS uses dnf or yum, and Debian/Ubuntu use apt. The command is different for each, as shown in the examples above.
Do I need to run apt-get update before installing jq?
Yes, on Debian/Ubuntu systems, you need to update the package list first, otherwise apt may not find the package or may install an older version. The command is apt-get update && apt-get install -y jq.
Is there a way to install jq without modifying the Dockerfile?
Yes, you can use the postCreateCommand in devcontainer.json. This is a good option if you don’t have a Dockerfile or want to keep the image clean. Just add the install command as a string in the JSON.
What if I’m using a remote container (e.g., on a server)?
The same principles apply. The container is still ephemeral, so you need to install jq during the build or post-create phase. The commands are the same, just executed in the remote environment. Make sure you have the necessary permissions to install packages.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Valheim Server Not Showing in Community List Fixes
- DisplayPort vs HDMI: Which Cable Should You Use?
- Soundbar vs 2.1 Speaker System: Which Is Better?
- Slack Channels for Construction Projects: Setup Guide
- Surface Won’t Turn On: Quick Fixes1.8 h
- Survive Lava for Brainrot Tier List170 points