docker-guide

SKILL.md

Docker Guide for Shopify/Remix Apps

This guide covers how to containerize your Shopify App for consistent deployment across any VPS or cloud provider.

1. Production Dockerfile (Multi-stage)

This optimized Dockerfile uses multi-stage builds to keep the final image size small (<200MB usually) and secure.

# base node image
FROM node:20-alpine AS base

# set for base and all layer that inherit from it
ENV NODE_ENV=production

# Install all node_modules, including dev dependencies
FROM base AS deps
WORKDIR /myapp
ADD package.json package-lock.json ./
# Or COPY package.json pnpm-lock.yaml ./ if using pnpm
RUN npm ci --include=dev

# Setup production node_modules
FROM base AS production-deps
WORKDIR /myapp
COPY --from=deps /myapp/node_modules /myapp/node_modules
ADD package.json package-lock.json ./
RUN npm prune --omit=dev

# Build the app
FROM base AS build
WORKDIR /myapp
COPY --from=deps /myapp/node_modules /myapp/node_modules
ADD . .
RUN npm run build

# Finally, build the production image with minimal footprint
FROM base
WORKDIR /myapp
COPY --from=production-deps /myapp/node_modules /myapp/node_modules
COPY --from=build /myapp/build /myapp/build
COPY --from=build /myapp/public /myapp/public
COPY --from=build /myapp/package.json /myapp/package.json
COPY --from=build /myapp/prisma /myapp/prisma

# Start the server
CMD ["npm", "run", "start"]

2. Local Development (docker-compose.yml)

Don't install Postgres/Redis locally on your Mac. Run them in Docker.

services:
  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: shopify_app
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    restart: always
    ports:
      - "6379:6379"
    command: redis-server --save 60 1 --loglevel warning

volumes:
  db_data:

3. Important Notes for Shopify Apps

SHOPIFY_APP_URL

In production, your SHOPIFY_APP_URL must match your domain (e.g., https://app.example.com). When running in Docker behind a proxy (like Nginx), ensure X-Forwarded-Proto headers are passed, otherwise Remix/Shopify auth might think it's HTTP and reject the session.

Port Mapping

Remix usually runs on port 3000. In Docker: EXPOSE 3000 And map it when running: docker run -p 8080:3000 my-app

Alpine Issues

If you use extensive native modules (like sharp or some crypto libs), Alpine might miss dependencies. If builds fail, switch from node:20-alpine to node:20-slim.

4. Commands

# Build
docker build -t my-shopify-app .

# Run locally to test
docker run -p 3000:3000 --env-file .env my-shopify-app
Weekly Installs
4
First Seen
Jan 25, 2026
Installed on
gemini-cli4
claude-code4
codex4
opencode4
antigravity3
github-copilot3