Dockerized setup

Dockerized setup

Get started quickly with a Dockerized zkSync node using npx zksync-cli dev start! This tool simplifies local environment setups and other zkSync operations. Learn more and in the zkSync CLI documentation. Or follow the instructions below to set up Dockerized node manually.

Dockerized local setup: installation & setup

Let's delve into the setup process for Dockerized Local Testing Environment.


Make sure Docker and docker-compose are installed on your system. If not, follow the installation guideopen in new window. Familiarity with the zkSync Hardhat plugins is also recommended. If you're new to zkSync development with Hardhat, check out the getting started section here.

Setting up the testing environment

To clone the dockerized project, use the following command:

git clone

Starting the local node

To launch the zkSync Era locally, run the script:

cd local-setup

This command initiates three docker containers:

  • Postgres: The database for zkSync.
  • Local Geth node: The L1 for zkSync.
  • The zkSync node itself.


The first script execution should go uninterrupted. If the bootstrapping process halts unexpectedly, reset the local zkSync state and try again. The process can take up to 10 minutes to start (only the first time!).

Network details

By default, the HTTP JSON-RPC API is served via port 3050, while the WebSocket (WS) API is accessed through port 3051.

  • L1 RPC: http://localhost:8545
  • L2 RPC: http://localhost:3050
  • WS API http://localhost:3051
  • Network Id: 270

Resetting the zkSync state

To reset the zkSync state, run the ./ script:


In case of a "permission denied" error, execute it with root privileges:

sudo ./

Update docker images

The script will also pull the most recent Docker images so it can be used to update the dockerized local setup.

Working with rich wallets

The local zkSync setup includes "rich" wallets preloaded with substantial amounts of ETH on both L1 and L2. You can find a complete list of the accounts' addresses along with the corresponding private keys hereopen in new window.


Rich wallets only hold ETH. If you need to test with ERC20 tokens, you'd need to deploy them yourself.

Employing a custom database or Ethereum node

To use a custom Postgres database or Layer 1 node, modify the environment parameters in the docker-compose file:

  - DATABASE_URL=postgres://postgres@postgres/zksync_local
  - ETH_CLIENT_WEB3_URL=http://geth:8545

DATABASE_URL represents the URL to the Postgres database, and ETH_CLIENT_WEB3_URL refers to the URL to the HTTP JSON-RPC interface of the L1 node.

Writing and running tests locally

Next, we'll explore how to write and execute tests locally. We'll use mocha and chai for testing.

Project configuration

  1. Start by creating a new Hardhat project. If you need guidance, follow the getting started guide.

  2. To incorporate the test libraries, execute:

yarn add -D mocha chai @types/mocha @types/chai
  1. Add the following lines to your package.json in the root folder:
"scripts": {
    "test": "NODE_ENV=test hardhat test"

This script makes it possible to run tests in a Hardhat environment with the NODE_ENV env variable set as test.

Configuring tests

  1. Adjust hardhat.config.ts to use the local node for testing:
import "@matterlabs/hardhat-zksync-deploy";
import "@matterlabs/hardhat-zksync-solc";

// dynamically changes endpoints for local tests
const zkSyncTestnet =
  process.env.NODE_ENV == "test"
    ? {
        url: "http://localhost:3050",
        ethNetwork: "http://localhost:8545",
        zksync: true,
    : {
        url: "",
        ethNetwork: "goerli",
        zksync: true,

module.exports = {
  zksolc: {
    version: "latest", // Uses latest available in
    settings: {},
  // defaults to zkSync network
  defaultNetwork: "zkSyncTestnet",
  networks: {
    hardhat: {
      zksync: true,
    // load test network details
  solidity: {
    version: "0.8.17",

Writing test scripts

  1. Now, create your first test! Construct a test/main.test.ts file with the following code:
import { expect } from "chai";
import { Wallet, Provider, Contract } from "zksync-web3";
import * as hre from "hardhat";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";


async function deployGreeter(deployer: Deployer): Promise<Contract> {
  const artifact = await deployer.loadArtifact("Greeter");
  return await deployer.deploy(artifact, ["Hi"]);

describe("Greeter", function () {
  it("Should return the new greeting once it's changed", async function () {
    const provider = Provider.getDefaultProvider();

    const wallet = new Wallet(RICH_WALLET_PK, provider);
    const deployer = new Deployer(hre, wallet);

    const greeter = await deployGreeter(deployer);

    expect(await greeter.greet()).to.eq("Hi");

    const setGreetingTx = await greeter.setGreeting("Hola, mundo!");
    // wait until the transaction is mined
    await setGreetingTx.wait();

    expect(await greeter.greet()).to.equal("Hola, mundo!");

Execute the test file with:

yarn test

Well done! You've successfully run your first local tests with zkSync Era.

For a complete example of a Hello World project set up with tests following this Dockerized setup, check hereopen in new window