Devenv
Devenv is a Nix-based tool for defining and managing fully reproducible development environments for local workstations or continuous integration (CI) systems. It works like a dependency manager for your entire development stack.
Instead of manually installing and configuring PHP, Node.js, MySQL, Redis, or other services, you describe your setup once in a devenv.nix file. Devenv then installs and runs the exact versions you specify, ensuring consistency across every developer’s machine.
Devenv lets you choose specific versions of binaries (e.g., PHP, Node, or npm) and configure and run services like MySQL, Redis, or OpenSearch. All binaries and service states are stored on a per-project basis, providing an isolated yet native development environment.
Unlike Docker or virtual machines, Devenv does not use containerization or virtualization. Instead, all services and binaries run natively on your host system. This makes it an appealing choice for Shopware core contributors or advanced users who want consistent local and CI builds.
Required on your host
Devenv provides project-local PHP, Node, Composer and services via Nix, so you don't need to install those runtimes globally for a project that uses Devenv.
On the host you only need a minimal toolchain:
- Nix package manager
- Git
- Optional: Docker Engine, only if you plan to run additional containerized services alongside Devenv
See the Shopware 6 requirements for general system requirements and supported versions. Devenv will provide the exact runtime versions per project.
Note: If you previously installed Nix using an older single-user script or via a package manager (for example,
brew install nix), remove it first to prevent permission or path conflicts. Removing/nixdeletes the global Nix store and may require elevated privileges. Usesudoif appropriate and double-check before running destructive commands.
Installation
Nix
Devenv is built on top of Nix, so you need to install it first. The Nix community recommends using the cross-platform Determinate Systems installer, which provides a fast, consistent setup across macOS, Linux, and WSL2 that requires no manual configuration:
curl -L https://install.determinate.systems/nix | sh -s -- installThis installs Nix in multi-user mode and automatically configures your shell. If you prefer, you can still use the official Nix installer, but it may require additional manual steps, such as updating your shell profile or enabling the Nix daemon.
For CI pipelines, Docker images, or other non-interactive environments, you can skip the Determinate Systems installer and invoke Nix directly using nix-shell or Nix Flakes. Use nix-shell for a simple, one-off environment defined by a shell.nix file. Use Nix Flakes for more reproducible builds and shared dependency management across systems or teams.
After installation, restart your terminal to load Nix’s environment variables automatically. Alternatively, to avoid restarting, you can load Nix manually in your current shell session:
# Load Nix into your current shell session
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.shThe Determinate Systems installer also handles shell integration, including Zsh and Oh My Zsh, so you don't need to manually copy Nix configuration lines into your shell startup files.
WARNING
If you have previously installed Nix using an older single-user script or via a package manager (for example, brew install nix), remove it first to prevent permission or path conflicts:
rm -rf ~/.nix-profile ~/.nix-defexpr ~/.nix-channels ~/.local/state/nix
rm -rf /nixRemoving /nix deletes the global Nix store and may require elevated privileges. Only run these commands if you intend to completely remove previous Nix installations.
If Nix commands aren’t available after installation, restart your terminal or run source ~/.zshrc.
Install Devenv
Once Nix is installed, install or update Devenv with the Nix profile command:
nix profile install github:cachix/devenv/latestYou can find the full installation guide and advanced options in the official Devenv documentation.
Quick checks (verify host & Devenv)
Run these to confirm your host environment is ready:
# Nix installed and on PATH
nix --version
# Devenv installed and available
devenv --version
which devenv
# Direnv (optional)
direnv --version || echo "direnv not installed"
# Basic sanity: list Devenv commands
devenv help
# Check few common ports (macOS / Linux examples)
lsof -i :8000 -i :3306 -i :6379 || ss -tulpn | grep ':8000\|:3306\|:6379'Shopware
Depending on your goals, you can either create a new Shopware project using the production template or contribute to the Shopware core, which already includes a devenv.nix file.
Once your project includes a devenv.nix file, you can start the environment:
devenv upWARNING
Before starting Devenv, ensure that common service ports (e.g., 8000, 3306, 6379) are not already in use. If they are, Devenv will fail to start the corresponding services.
Check for active services:
Configure your database connection (optional)
Verify your .env file points to the correct database:
# <PROJECT_ROOT>/.env
DATABASE_URL="mysql://shopware:shopware@127.0.0.1:3306/shopware?sslmode=disable&charset=utf8mb4"If you changed your MySQL port or user in devenv.local.nix, update these values here as well.
Launch Devenv and install Shopware
Start Devenv in the project directory:
devenv upThen open a new terminal and enter the Devenv shell, which provides PHP, Composer, Node.js, npm, etc.:
devenv shellInside the Devenv shell, install Shopware:
bin/console system:install --basic-setup --create-database --forceOnce installation completes, open http://localhost:8000/admin in your browser. You should see the Shopware Admin interface.
The default credentials are:
- User:
admin - Password:
shopware
INFO
On Windows with WSL2, change the default sales channel domain to http://localhost:8000. Use http, not https.
To create a full test setup with demo data, run:
composer setup && APP_ENV=prod bin/console framework:demodata && APP_ENV=prod bin/console dal:refresh:indexIf installation completes without schema creation, run bin/console database:migrate.
Direnv (optional)
Direnv makes it easier to work with multiple Devenv projects by automatically activating the correct environment when you enter a project directory. It's optional but recommended for a smoother workflow.
With Direnv, you don’t have to run devenv shell manually every time you use the binaries. The environment loads automatically.
You still need to start the services once with devenv up.
First, install Direnv:
Add the Direnv hook to your shell configuration file:
After configuring your shell, reload it or restart your terminal.
First use
When you enter a Devenv project directory for the first time, allow Direnv to load the environment:
direnv allowIf you change the Devenv configuration or your .envrc file after running direnv allow, reload the environment with:
direnv reloadDirenv will now automatically activate the Devenv environment whenever you enter the directory.
See the official Automatic Shell Activation guide for more details.
Default services
When you start Devenv with devenv up, Shopware automatically provides several core services. You can access them using the following addresses:
| Service | Default address | Description |
|---|---|---|
| MySQL | mysql://shopware:shopware@127.0.0.1:3306 | Primary database for Shopware. |
| Mailhog (SMTP) | smtp://127.0.0.1:1025 | Local mail capture for testing email. |
| Redis (TCP) | tcp://127.0.0.1:6379 | Used for caching and sessions. |
| Caddy | http://127.0.0.1:8000 | Web server. |
| Adminer | http://127.0.0.1:9080 | Database management tool. |
TIP
The MySQL service listens on port 3306 and stores its data in <PROJECT_ROOT>/.devenv/state/mysql. Use 127.0.0.1 instead of localhost when connecting to MySQL.
Redis
Redis is used for caching and sessions and runs on tcp://127.0.0.1:6379.
If Redis fails to start with an error such as Failed to configure LOCALE for invalid locale name, set a valid locale before starting Devenv:
export LANG=en_US.UTF-8Caddy
Caddy is an open-source web server written in Go with automatic HTTPS. It serves your local Shopware instance by default at http://127.0.0.1:8000.
Adminer
Adminer is a full-featured, lightweight database management tool written in PHP. You can use it to view and manage your Shopware database: http://127.0.0.1:9080.
Default credentials:
- User:
shopware - Password:
shopware
Mailhog
MailHog is an email testing tool that intercepts outgoing messages so you can preview them in your browser: http://localhost:8025.
Customize your setup
You can customize the predefined Devenv services to match your local needs—for example, changing virtual hosts, database names, or environment variables. You can override defaults to match your local dev setup, e.g., to free ports or change domains.
To override or extend the defaults, create a devenv.local.nix file in your project root. This file lets you disable built-in services, adjust configuration, or add new ones that your project requires.
After editing devenv.local.nix, reload your environment to apply the changes.
Example:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
# Disable a service
services.adminer.enable = false;
# Use a custom virtual host
services.caddy.virtualHosts."http://shopware.swag" = {
extraConfig = ''
root * public
php_fastcgi unix/${config.languages.php.fpm.pools.web.socket}
file_server
'';
};
# Customize nodejs version
languages.javascript = {
package = pkgs.nodejs-18_x;
};
# Override an environment variable
env.APP_URL = "http://shopware.swag:YOUR_CADDY_PORT";
}For a full list of all available services and their configuration options, refer to the official Devenv documentation.
If you're not using Direnv, remember to reload the environment manually after changing any *.nix file:
exit
devenv shellAll binaries installed by Devenv are located in <PROJECT_ROOT>/.devenv/profile/bin.
You can search for available packages on NixOS package search.
This comes in handy if you want to configure interpreters in your IDE.
WARNING
Do not commit service tokens or credentials to version control. Store secrets in .env or a secret manager.
Enable Blackfire (optional)
To enable Blackfire profiling in your Devenv setup, add the following configuration to your devenv.local.nix file:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
services.blackfire.enable = true;
services.blackfire.server-id = "<SERVER_ID>";
services.blackfire.server-token = "<SERVER_TOKEN>";
services.blackfire.client-id = "<CLIENT_ID>";
services.blackfire.client-token = "<CLIENT_TOKEN>";
}Enable XDebug (optional)
To enable Xdebug for debugging or profiling, add the following configuration to your devenv.local.nix file:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
# XDebug
languages.php.extensions = [ "xdebug" ];
languages.php.ini = ''
xdebug.mode = debug
xdebug.discover_client_host = 1
xdebug.client_host = 127.0.0.1
'';
}After modifying your devenv.local.nix file, reload your environment.
Use MariaDB instead of MySQL (optional)
To switch from MySQL to MariaDB, update your devenv.local.nix file:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
services.mysql.package = pkgs.mariadb;
}Use a custom MySQL port (optional)
You can change the default MySQL port if it conflicts with another service on your system:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
services.mysql.settings = {
mysqld = {
port = 33881;
};
};
}After any change, run devenv reload to apply updates.
Customize Caddy ports or virtual hosts (optional)
You can adjust the Caddy web server configuration to use a different port or virtual host.
Use a custom Adminer port (optional)
If you need to change the default Adminer port (for example, to avoid conflicts with another service), update your devenv.local.nix file:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
services.adminer.listen = "127.0.0.1:9084";
}After modifying devenv.local.nix, reload your environment.
Use Varnish (optional, advanced)
You can integrate Varnish into your local Shopware development setup to test reverse caching behavior. The following example shows how to configure Caddy and Varnish in your devenv.local.nix file:
# <PROJECT_ROOT>/devenv.local.nix
{ pkgs, config, lib, ... }:
{
# caddy config
services.caddy = {
enable = true;
# all traffic to localhost is redirected to varnish
virtualHosts."http://localhost" = {
extraConfig = ''
reverse_proxy 127.0.0.1:6081 {
# header_up solves this issue: https://discord.com/channels/1308047705309708348/1309107911175176217
header_up Host sw.localhost
}
'';
};
# the actual shopware application is served from sw.localhost,
# choose any domain you want.
# you may need to add the domain to /etc/hosts:
# 127.0.0.1 sw.localhost
virtualHosts."http://sw.localhost" = {
extraConfig = ''
# set header to avoid CORS errors
header {
Access-Control-Allow-Origin *
Access-Control-Allow-Credentials true
Access-Control-Allow-Methods *
Access-Control-Allow-Headers *
defer
}
root * public
php_fastcgi unix/${config.languages.php.fpm.pools.web.socket}
encode zstd gzip
file_server
log {
output stderr
format console
level ERROR
}
'';
};
};
# varnish config
services.varnish = {
enable = true;
package = pkgs.varnish;
listen = "127.0.0.1:6081";
# enables xkey module
extraModules = [ pkgs.varnishPackages.modules ];
# it's a slightly adjusted version from the [docs](https://developer.shopware.com/docs/guides/hosting/infrastructure/reverse-http-cache.html#configure-varnish)
vcl = ''
# ...
# Specify your app nodes here. Use round-robin balancing to add more than one.
backend default {
.host = "sw.localhost";
.port = "80";
}
# ...
# ACL for purgers IP. (This needs to contain app server ips)
acl purgers {
"sw.localhost";
"127.0.0.1";
"localhost";
"::1";
}
# ...
'';
};
}After updating your devenv.local.nix, reload your development environment to apply the changes:
devenv reloadUse an older package version (optional, advanced)
Sometimes, you may want to pin a service to an older version to, for example, ensure compatibility with legacy components or reproduce a previous environment state.
Here are examples showing how to use older versions of MySQL and RabbitMQ in your devenv.local.nix configuration:
Example: Use a specific MySQL version:
{
services.mysql = let
mysql8033 = pkgs.mysql80.overrideAttrs (oldAttrs: {
version = "8.0.33";
# the final url would look like this: https://github.com/mysql/mysql-server/archive/mysql-8.0.33.tar.gz
# make sure the url exists.
# alternatively you could use that url directly via pkgs.fetchurl { url = "xyz"; hash="xyz";};
# for reference see the [different fetchers](https://ryantm.github.io/nixpkgs/builders/fetchers/#chap-pkgs-fetchers)
src = pkgs.fetchFromGitHub {
owner = "mysql";
repo = "mysql-server";
rev = "mysql-8.0.33";
# leave empty on the first run, you will get prompted with the expected hash
sha256 = "sha256-s4llspXB+rCsGLEtI4WJiPYvtnWiKx51oAgxlg/lATg=";
};
});
in
{
enable = true;
package = mysql8033; # use the overridden package
# ...
};
}Example: Use a specific RabbitMQ version:
{
services.rabbitmq = let
rabbitmq3137 = pkgs.rabbitmq-server.overrideAttrs (oldAttrs: {
version = "3.13.7";
src = pkgs.fetchurl {
url = "https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-3.13.7.tar.xz";
sha256 = "sha256-GDUyYudwhQSLrFXO21W3fwmH2tl2STF9gSuZsb3GZh0=";
};
});
in
{
enable = true;
package = rabbitmq3137; # use the overridden package
};
}Pinning versions may increase build time; use only when necessary.
Maintenance (recommended)
Run devenv gc periodically to remove unused packages, services, and caches. This helps free disk space and keeps your environment clean.
Use devenv down to stop services first. If processes remain, as a last resort terminate them manually:
kill $(ps -ax | grep /nix/store | grep -v "grep" | awk '{print $1}')If you can’t access http://127.0.0.1:8000 in your browser, try http://localhost:8000 instead. This issue is common when using WSL2 on Windows.
On macOS or Linux, the app should be available at http://127.0.0.1:8000.