Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk6 min

Capstone: Dockerize Your Own App End to End

A step-by-step path from an existing app to a running Docker image, covering Dockerfile basics, build optimization, Compose, persistence and production checks.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To Dockerize an app, you write a Dockerfile that describes how to build an image, build it with docker build, and run it with docker run while publishing the app’s port. Add Docker Compose only when you have run options or companion services (a database, cache or queue) worth recording. Docker’s documentation puts the split this way: “A Dockerfile provides instructions to build a container image while a Compose file defines your running containers.” (Docker Docs). This guide walks the path in order. The commands are an instructional workflow and were not run against your project, so adapt them to your language and framework.

Step 1: Inspect the app before writing anything

A Dockerfile is a written-down version of how your app already runs. Collect these facts first:

As an Amazon Associate I earn from qualifying purchases.

  • Language and runtime version (for example, the exact Node, Python, Java or Go version you develop against).
  • Dependency manager and manifest files (package.json and a lockfile, requirements.txt, pom.xml, go.mod, and so on).
  • Entry point: the exact command that starts the app.
  • System packages needed, especially for native extensions.
  • Listening port, and whether the app binds to 0.0.0.0 rather than only localhost. An app bound only to localhost inside a container is unreachable from the host.
  • Configuration inputs: environment variables, config files, secrets.
  • External services: databases, caches, queues, object storage.

If you can, confirm the app runs correctly outside Docker first. Debugging an app bug and a container bug at the same time is slow. No single Dockerfile fits every framework, so treat the examples below as a pattern.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step 2: Write the first Dockerfile

Docker’s Writing a Dockerfile page covers the instruction set. The sketch below uses a Node.js web app purely as an illustration; swap the base image, install command and start command for your stack.

FROM node:22
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

What each line does:

  • FROM picks the base image. Pin a specific version tag rather than relying on a floating latest.
  • WORKDIR sets the directory for the following instructions and for the running container.
  • COPY package*.json ./ and RUN npm ci bring in only the dependency manifests and install from them.
  • COPY . . copies the rest of the source afterwards, so editing code does not invalidate the dependency layer.
  • EXPOSE documents the container port. It does not publish it; you still map a host port at run time.
  • CMD defines the startup command. Prefer the exec (JSON array) form so the app receives stop signals directly.

Step 3: Build and run it

  1. From the project root (where the Dockerfile lives), build: docker build -t my-app . The trailing dot is the build context.
  2. Run it, mapping a host port to the container port: docker run --rm -p 8080:3000 my-app
  3. Open http://localhost:8080. The format is host:container, so the right-hand number must match the port your app listens on.
  4. If it fails to start, read the output in the terminal, or run detached with -d --name my-app and use docker logs my-app. Check the container’s state with docker ps -a.

Common first-run failures: a wrong start command or path, a missing system package, an app bound to localhost only, and a port mismatch between -p and the app.

Step 4: Improve the build

Docker’s building best practices and its hands-on image lab, which covers layers, cache ordering, .dockerignore, non-root users, multi-stage builds, base-image choice and build secrets, are the references for this stage.

Add a .dockerignore early

The whole build context is sent to the Docker daemon, and COPY . . will pull in anything in it. Docker’s Compose quickstart-style guidance specifically demonstrates excluding .env so sensitive values do not end up in an image layer. A starting point:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
.git
node_modules
.env
*.log
Dockerfile
.dockerignore

Adjust it to your stack: local dependency folders, build output, virtual environments and editor files typically belong here.

Order layers for cache reuse

Docker reuses cached layers until an instruction’s inputs change. Copy dependency manifests and install first, then copy source, as in the sample above. Day-to-day code edits then rebuild only the last layers.

Use a multi-stage build when build tools are not needed at runtime

Multi-stage builds let one stage compile or bundle the app and a later stage carry only what runs it. Docker says this can reduce image size and security exposure; how much depends on your app, so measure rather than assume.

FROM node:22 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-slim
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY package*.json ./
RUN npm ci --omit=dev
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Here compilers and dev dependencies stay in the first stage, and the final image runs as the non-root node user. For compiled languages the final stage may be even smaller, but only if the binary and its libraries are compatible with the chosen base.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a base image deliberately

Choice Good for Watch for
Full language image Easiest start; includes common build tools Larger, more contents to maintain
Slim variant Smaller runtime with common libraries Native dependencies may need extra packages
Alpine-based variant Very small footprint Different C library and tooling can break native dependencies; not universally best

Pick the smallest image your app and its native dependencies work on, then consider how you will debug it, since minimal images ship fewer diagnostic tools.

Keep secrets out of the image

Do not pass secrets through ordinary build arguments or commit them to the repository, because they can persist in image metadata or layers. Use Docker’s build-secret mechanism for build-time credentials, and a runtime secret facility appropriate to where you deploy.

Step 5: Decide whether you need Docker Compose

A single docker run is fine for one self-contained container. Compose earns its place when:

  • the app needs a database, cache or queue alongside it;
  • your run command has grown long (ports, env vars, volumes, networks) and you want it repeatable;
  • teammates need one command to bring up the same environment.

Compose can also describe a single service just to preserve its options. The Compose build specification lets a service point at your Dockerfile, and the Compose quickstart shows the basic workflow. Example compose.yaml for an app plus a database:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
services:
  web:
    build: .
    ports:
      - "8080:3000"
    environment:
      DATABASE_HOST: db
    depends_on:
      - db
  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - db-data:/var/lib/postgresql/data
    secrets:
      - db_password

volumes:
  db-data:

secrets:
  db_password:
    file: ./db_password.txt

Services reach each other by service name, so the app connects to host db, not localhost. Start everything with docker compose up --build and stop it with docker compose down. Keep db_password.txt out of version control and out of the build context.

Best Value
Docker Container Linux Devops Programming Coding T-Shirt
  • Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
  • Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Step 6: Plan for data and lifecycle

Data written only to a container’s writable layer disappears when the container is removed. Docker’s quickstart notes this explicitly. Stopping a container (docker stop) keeps that layer; removing it (docker rm, docker compose down) or recreating it after an image update does not.

Approach Survives container removal? Use for
Writable layer only No Temporary files, caches you can regenerate
Named volume Yes (until you delete the volume) Database files, uploads on a single host
External data service Yes, independent of the host Data that must outlive the whole deployment

Note that docker compose down -v deletes named volumes too, so use that flag deliberately.

Step 7: Review before production

Docker’s Use Compose in production guide describes applying production-specific configuration, typically with a second file merged over the base. Items to review:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Bind mounts of source code: useful in development, not in production, where the image should contain the code.
  • Published ports: expose only what must be reachable; keep database ports off the host.
  • Environment values and secrets: production credentials differ from development ones and should not live in the repository.
  • Restart policy: for example restart: always so services return after a crash or reboot.
  • Logging and monitoring: decide where logs go and how you will notice failures.
  • Updates: after changing code, rebuild and recreate only the affected service, e.g. docker compose build web then docker compose up --no-deps -d web.

A production override is applied like this:

docker compose -f compose.yaml -f compose.production.yaml up -d

Be clear about scope: Compose on a single server is a reasonable deployment for many small apps, but it is not a high-availability, multi-node orchestrated platform. If you need failover or scaling across machines, that is a different tool decision.

Final checklist

  • App runs outside Docker; port, entry point and dependencies known.
  • Dockerfile uses a pinned base image, installs dependencies before copying source, and runs as a non-root user.
  • .dockerignore excludes .git, local dependencies and .env.
  • Multi-stage build used if build tooling is not needed at runtime.
  • Persistent data lives in a volume or external service.
  • Compose added if there are companion services or a run command worth keeping; production overrides reviewed.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.