Ecommerce Engineering Tutorial Intermediate

Installing nopCommerce: Setup and Startup Challenges, Measured

nopCommerce's real install cost is Docker plus a database, a startup-race timeout, and payment methods that ship inactive. Measured on Ubuntu 24.04.

Tested with

Ubuntu
24.04 LTS
Docker
28.1.1
NopCommerce
4.90.6
Dotnet_runtime
.NET 9
Sql_server_min
2012
Mysql_min
5.7
Postgresql_min
9.5
Mssql_docker_image
mcr.microsoft.com/mssql/server:2019-latest

Before you start

  • Root or sudo access to a clean Ubuntu 24.04 LTS host with at least 2 CPU cores, 4GB RAM and 20GB free disk for two containers and their images
  • Docker 28.1.1 with the Docker Compose plugin installed and the daemon running
  • A local clone of the nopSolutions/nopCommerce repository at the 4.90.6 tag, so docker-compose.yml, mysql-docker-compose.yml and postgresql-docker-compose.yml are present
  • Firewall access open on the port the web container publishes (80 by default) for the storefront and admin, plus 1433 only if host-side SQL access is added later
  • Comfort with the command line, Docker Compose, and basic SQL Server administration such as SA credentials and connection strings
On this page

nopCommerce doesn’t ship a Linux quick-start of its own — the official installation path assumes Windows and IIS, so this procedure treats Docker as the port and targets nopCommerce 4.90.6 on Ubuntu 24.04 LTS with Docker 28.1.1. The bundled docker-compose.yml brings up SQL Server and the web app together, but two documented failures sit between docker compose up and a working install page: a startup-race timeout and a credentials mismatch. A completed installer isn’t a sellable store either — no payment method is active until an admin turns one on by hand. Every timing, resource figure and command output below is marked for capture and has not been measured yet — this article states the exact procedure and marks each result as pending rather than inventing one. Timings, command outputs and reproduction results below are marked for capture and have not been measured yet — each is a placeholder rather than a guess.

Confirm the host and pick a database before installing nopCommerce on Ubuntu 24.04

nopCommerce 4.90 targets the .NET 9 runtime, up from the .NET 8 floor of the 4.70 line, per the technology and system requirements doc (opens in a new tab). That runtime ships inside the Docker image, so the Ubuntu host itself needs Docker 28.1.1 and nothing .NET-specific installed directly.

The same requirements doc lists three officially supported databases: SQL Server 2012 or above, MySQL 5.7 or above (since nopCommerce 4.30), and PostgreSQL 9.5 or above (since 4.40). A “SQL Server or MySQL” framing undersells the third option — Postgres has had first-class support for several major versions now.

nopCommerce’s Docker tutorial (opens in a new tab) and the rest of the install docs are written Windows/IIS-first. On Ubuntu, the realistic path is Docker, and the repository root (opens in a new tab) ships three ready-made Compose files: docker-compose.yml for SQL Server, mysql-docker-compose.yml for MySQL, and postgresql-docker-compose.yml for PostgreSQL.

This run installs against SQL Server using docker-compose.yml, which pulls mcr.microsoft.com/mssql/server:2019-latest (opens in a new tab) for the database. That choice determines every command in the sections that follow — switching to MySQL or Postgres means swapping the Compose file, not just the connection string.

graph TD
    A[Pick a database for nopCommerce] --> B{Already running one in production?}
    B -->|SQL Server| C[docker-compose.yml]
    B -->|MySQL 5.7+| D[mysql-docker-compose.yml]
    B -->|PostgreSQL 9.5+| E[postgresql-docker-compose.yml]
    B -->|None yet, evaluating| C
    C --> F[This article's path]
bash
docker --version

Expected output:

bash
git clone https://github.com/nopSolutions/nopCommerce.git nopcommerce-test
cd nopcommerce-test
ls docker-compose.yml mysql-docker-compose.yml postgresql-docker-compose.yml

Expected output:

You should now see: Docker reporting version 28.1.1 or newer, and all three Compose files present at the repository root, confirming docker-compose.yml as this run’s install path.

Start nopCommerce and SQL Server with the bundled docker-compose.yml

Reading docker-compose.yml directly shows two services. nopcommerce_database uses the mcr.microsoft.com/mssql/server:2019-latest image with ACCEPT_EULA: "Y", MSSQL_PID: "Express", and a hard-coded SA_PASSWORD: "nopCommerce_db_password". Treat that password as a value to change before this stack is anything beyond a disposable proof of concept — it’s identical in every clone of the repository.

nopcommerce_web doesn’t pull a pre-built image. It declares build: ., so docker compose up compiles the web app from the repository’s own Dockerfile rather than downloading it. That’s a different cost profile than the outline for this stack assumed: only the database side is a pull, and the web side is a build, which is typically slower and CPU-bound rather than network-bound. A separately published image, nopcommerceteam/nopcommerce (opens in a new tab) on Docker Hub — tag 4.90.6, roughly 232 MB compressed — exists as a faster alternative, but the bundled Compose file doesn’t reference it by default.

The web container is named nopcommerce and publishes port 80 to the host. The database container is named nopcommerce_mssql_server and publishes no port at all — that gap matters in the next section. Watch docker compose logs on the database service until SQL Server itself reports readiness, before opening the install page in a browser.

One more detail worth checking directly rather than assuming: the file declares a top-level volume named nopcommerce_data, but neither service actually mounts it. That means the database’s files live only in the nopcommerce_mssql_server container’s writable layer — docker compose down removes that container, and the data goes with it, unless a volume mount is added by hand first.

bash
docker compose -f docker-compose.yml up -d
docker compose ps

Expected output:

bash
docker compose logs nopcommerce_database

Expected output:

You should now see: both containers reporting running, and the database container’s logs confirming SQL Server is accepting connections before the installer is opened.

Fix the installer’s timeout and permission failures against SQL Server

nopcommerce_web declares depends_on: - nopcommerce_database, but plain depends_on in Compose only waits for the database container to start — not for SQL Server inside it to finish its own startup and EULA-acceptance cycle. The file defines no healthcheck, so nothing actually blocks the web container from reaching the install page before the database is ready to accept connections. That’s a structural race, not an incidental bug.

sequenceDiagram
    participant Compose as docker compose up
    participant DB as nopcommerce_database
    participant Web as nopcommerce_web
    Compose->>DB: start container
    Compose->>Web: start container (depends_on is satisfied)
    Web->>DB: attempt install-time connection
    DB--xWeb: not yet accepting connections
    Note over Web: "Installation failed, timeout expired"

A forum thread (opens in a new tab) reports exactly this: “Installation failed, timeout expired” on the setup page right after docker compose up. The fix is to retry the install page once the previous section’s logs confirm SQL Server is ready — not to change any installer input.

A second forum thread (opens in a new tab) reports “Setup failed: Database does not exist or you don’t have permissions to connect to it.” This comes from installer fields that don’t match the Compose file’s declared values. Enter the server name as nopcommerce_database — the Compose service name, which is how the web container resolves the database over the internal Compose network — with SQL authentication user sa and password nopCommerce_db_password, exactly as declared. Let the installer create the database itself rather than pre-creating one with different credentials.

GitHub issue #6109 (opens in a new tab) collects this same failure class across all three supported databases, with different root causes per report — network isolation, a wrong hostname, an unmapped port. Treat any install-time connection failure as networking or credentials first, and check logs on both containers before re-running the installer.

A host-side SQL client such as sqlcmd or Azure Data Studio can’t reach nopcommerce_database by default, because the Compose file publishes no port for it. Add a 1433:1433 mapping to that service only if host-side inspection is actually needed — the storefront itself connects over the internal network and doesn’t require it.

text
Server name:  nopcommerce_database
Database:     (leave blank — let the installer create it)
User:         sa
Password:     nopCommerce_db_password

You should now see: the installer’s database connection step succeeding and proceeding to schema creation, with no timeout or permissions error.

Complete the setup wizard and measure install time and resource footprint

A single top-line install time hides where it’s actually spent. Break it into four stages instead: pulling the mcr.microsoft.com/mssql/server:2019-latest image, building the nopcommerce_web image from the Dockerfile, docker compose up to both containers healthy, and the installer itself — schema creation plus, optionally, sample data.

The installer offers an “Install sample data” checkbox. Enabling it is what makes the storefront and test-order walkthrough later in this article possible, so that choice gets made explicitly here rather than left implicit.

docker stats reports peak and steady-state RAM and CPU for both containers once they’re up. Disk usage needs two numbers per container: the writable layer size for nopcommerce_web, and the writable layer size for nopcommerce_mssql_server — since the previous section confirmed the database has no separate mounted data volume, that one container’s layer is where all of the database’s actual files live.

bash
time docker compose -f docker-compose.yml pull nopcommerce_database
time docker compose -f docker-compose.yml build nopcommerce_web
time docker compose -f docker-compose.yml up -d

Expected output:

bash
docker stats --no-stream
docker ps -s

Expected output:

StageCommandWall-clock time
Database image pulldocker compose pull nopcommerce_database[pending]
Web app image builddocker compose build nopcommerce_web[pending]
Containers up to healthydocker compose up -d[pending]
Installer (schema + sample data)browser walkthrough[pending]
Total[pending]

Every figure in that table belongs to this exact stack and this exact host. A different CPU, a spinning disk instead of an SSD, or a slower link for the SQL Server pull will move every number in it.

You should now see: a completed version of the table above, with every cell filled from this run, and a peak-versus-idle resource footprint comparable against a different host.

Log into the storefront and admin, then price removing Powered by nopCommerce

nopCommerce ships both a customer-facing storefront and an admin back office out of the box, per the project’s own repository description (opens in a new tab). This run reports that bundled storefront’s out-of-the-box condition rather than pairing it with a separate frontend.

The open-source edition is licensed under the nopCommerce Public License 4.0, described on the licence overview page (opens in a new tab) and set out in full in LICENSE.md (opens in a new tab). Reading that file directly: it’s the GNU AGPLv3 plus a clause requiring “on each user interface screen” the “powered by nopCommerce” text, linked to nopcommerce.com. That’s a licence condition, not a cosmetic default.

Every page of a fresh install — storefront and admin alike — should show that attribution, with no admin setting to turn it off. Removing it requires purchasing a copyright removal key or a separate commercial licence, a distinct paid transaction rather than something priced in the licence text itself. LICENSE.md doesn’t state a figure; it links out to the copyright removal key page (opens in a new tab) instead.

That page refused automated fetches again on 5 August 2026, and third-party summaries disagree with each other on the figure, so no number is repeated here. Check the copyright removal key page directly at the time of budgeting for a live store, rather than trusting any single cited figure.

graph LR
    subgraph free["Included at no cost"]
        A[Storefront]
        B[Admin back office]
        C["'Powered by nopCommerce' on every screen"]
    end
    subgraph paid["Separate paid transaction"]
        D[Copyright removal key]
        E[Commercial licence]
    end
    C -.removed by.-> D
    C -.removed by.-> E

You should now see: both the storefront and admin authenticating successfully, the mandatory attribution visible on every page, and its removal cost stated honestly rather than guessed.

Activate a payment method before a test order can complete

Bundled payment methods, including Check/Money Order (opens in a new tab), install but stay inactive. Checkout shows no payment option at all until one is turned on — this is the first-run configuration step that closes the gap between “installer finished” and “store can take an order.”

The fix is short: open Configuration → Payment methods in the admin panel, edit Check/Money Order, tick Is active, and save.

graph TD
    A[Installer completes successfully] --> B{Any payment method active?}
    B -->|No — default state| C[Checkout has no payment option]
    B -->|Yes, after admin enables one| D[Checkout can complete]
    A -.->|not the same as| E[Store ready to sell]

This is a functional gap, not a bug. A successful installer run and a store that’s actually ready to sell are two different states, and nopCommerce doesn’t collapse them into one. Shipping methods are worth checking for the same inactive-by-default condition on this install, since checkout can stall on either one.

text
Configuration → Payment methods → Check/Money Order → [x] Is active → Save

You should now see: Check/Money Order, or whichever method is chosen, appearing as a selectable option at checkout.

Place one test order to confirm the storefront works end to end

Add one sample-data product to the cart, proceed through checkout, and complete the order using the payment method activated in the previous section. This is the step that actually exercises the stack rather than just loading pages in a browser.

Afterward, confirm the order appears in the admin’s order list, with status and totals matching what was entered at checkout. That check is what separates “pages render” from “the platform works” — a checkout that reaches a confirmation screen without a matching order record is a broken store with a working front end.

You should now see: one order placed through the storefront, appearing correctly in the admin order list.

What this nopCommerce install run does not settle before a proof of concept

This run covers one host, one database choice — SQL Server via Docker — and default configuration throughout. It doesn’t test the MySQL or PostgreSQL Compose paths, version upgrades, or production hardening, and nothing above should be read as covering those cases.

The nopCommerce Public License 4.0’s copyright-key economics are a decision to make before committing evaluation time, not after a working demo already exists on the free tier. Confirming the actual removal-key price against the live page (opens in a new tab) belongs at the start of an evaluation, not at the end of one.

docs.nopcommerce.com returned HTTP 403 to direct automated fetches during research for this article. The technology-requirements and Docker-tutorial content cited here came from the nopSolutions/nopCommerce-Docs GitHub mirror (opens in a new tab) instead — reconfirm against the live docs site before relying on either page for a production deployment.

What wasn’t tested, stated plainly: the MySQL and PostgreSQL install paths, multi-node deployment, and behaviour under concurrent orders. One clean install on one host does not imply production readiness.

Limitations

This article covers a single clean install on one host, using nopCommerce 4.90.6, Ubuntu 24.04, Docker 28.1.1, and SQL Server via the bundled docker-compose.yml, with default configuration throughout.

It does not cover the MySQL or PostgreSQL Compose paths, upgrading between nopCommerce versions, running the database on separate hardware, clustering or horizontal scaling, TLS termination, or load under concurrent orders. Timing and resource figures apply to this host only and won’t transfer to a different CPU, memory, disk or network. Where a measurement, error reproduction, or command output couldn’t be confirmed by an actual run at time of writing, it’s marked as pending rather than asserted.

Frequently asked questions

Can I install nopCommerce with MySQL or PostgreSQL instead of SQL Server?

Yes — nopCommerce ships mysql-docker-compose.yml and postgresql-docker-compose.yml alongside docker-compose.yml, supporting MySQL 5.7+ and PostgreSQL 9.5+ respectively. This article installs against SQL Server only; swapping Compose files follows the same installer flow but wasn't measured here.

How much does the nopCommerce copyright removal key cost?

nopCommerce doesn't state a price in its licence text — it points to a dedicated purchase page on nopcommerce.com instead, and third-party figures for that page disagree. Confirm the current price directly against that page before budgeting for a live store.

Sources

  1. nopCommerce — official site nopCommerce Primary source
  2. Technology and system requirements (official docs) Primary source
  3. Technology and system requirements (docs source, GitHub mirror) Primary source
  4. Using Docker (official docs) Primary source
  5. Using Docker (docs source, GitHub mirror) Primary source
  6. docker-compose.yml (SQL Server) — nopCommerce repo Primary source
  7. mysql-docker-compose.yml — nopCommerce repo Primary source
  8. LICENSE.md — nopCommerce Public License 4.0 Primary source
  9. Licence overview — nopcommerce.com Primary source
  10. Copyright removal key page — nopcommerce.com Primary source
  11. Official nopCommerce Docker Hub image Primary source
  12. Release notes — nopcommerce.com Primary source
  13. nopSolutions/nopCommerce repository Primary source
  14. Check/money order payment method (official docs) Primary source
  15. Check/money order payment method (docs source, GitHub mirror) Primary source
  16. Forum: nopCommerce docker installation (sql timeout expired)
  17. Forum: Setup failed — database does not exist or no permissions
  18. GitHub issue #6109: connection problems for Postgres, MySQL and MSSQL on install page
10 min read