plym Docs
    plym.io

    Installation

    Guide to install and troubleshoot plym.

    Updated Aug 04, 2026

    On this page

    Install plym on macOS or Linux with one command. It brings up Postgres, the API, and Caddy, installs the plym CLI, and publishes your first post.

    plym runs everywhere, including Windows. A one-click installation script through Powershell is on the roadmap. In the meantime, view FAQs on installing directly from source.

    The installer pulls the plymio/plym:latest image, extracts the project files into a directory, generates your secrets, starts the stack, and waits for the API to answer /health. It never touches an existing install: if the target directory is already there, it stops rather than writing into it.

    Prerequisites

    Requirement Why
    Docker with Compose v2 Runs the three containers. docker compose version must succeed.
    openssl Generates the JWT secret, the admin password, and the database password.
    curl Health checks and the API calls that publish the welcome post.
    lsof or nc Probes for a free port. Without either, the port check is skipped — see Troubleshooting.
    ~1 GB free disk The three images: plym 544 MB, Postgres 411 MB, Caddy 85 MB.

    The Docker daemon has to be running before you start. On macOS install Docker Desktop, OrbStack, or Colima. On Linux install Docker Engine and add your user to the docker group.

    Install

    curl -fsSL https://plym.io/install | sh

    The installer asks two questions:

    Name your blog Acme Docs
    Admin email (root@plym.local) docs@acme.com

    The blog name goes into config.yaml and the email becomes your superuser account. Press Enter on the email to accept root@plym.local.

    The first install pulls Postgres and Caddy, runs migrations, and downloads fonts, so it takes a few minutes. When it finishes:

      plym is live.
    
      Acme Docs
      ────────────────────────────────────────
      Blog       http://localhost:9173
      Admin      http://localhost:9173/blog/plym-admin
      API docs   http://localhost:9173/docs
      Hello post http://localhost:9173/blog/hello
    
      Sign in:
        Email      docs@acme.com
        Password   4f9c1a7be2d05836aa1c74e9
    
      Credentials saved to /home/you/plym/.plym-credentials

    Verify

    Open http://localhost:9173/blog/hello in a browser, then ask for the same URL as an agent would:

    curl -H 'Accept: text/markdown' http://localhost:9173/blog/hello
    Welcome to **plym**. Your instance is successfully deployed and running.
    
    ## Command Line Interface (CLI)
    
    plym includes a built-in CLI to streamline environment management and deployment.

    Two different content types from one URL means the render pipeline and Caddy are both working.

    Non-interactive install

    Pass the blog name and admin email as arguments to skip both prompts:

    curl -fsSL https://plym.io/install | sh -s "Acme Docs" "docs@acme.com"

    Install options

    Set these as environment variables on the sh process.

    Variable Default Effect
    PLYM_DIR plym Directory to install into, relative to your current directory.
    PLYM_PORT 9173 Starting port for the probe. The installer walks upward until it finds a free one.
    PLYM_IMAGE plymio/plym:latest Pin a tag from hub.docker.com/r/plymio/plym. Written to .env so plym update keeps the pin.
    PLYM_VERBOSE 0 Set to 1 to stream the full Docker and container logs instead of a spinner.
    PLYM_CONFIG_HOME ~/.config/plym Where the CLI records which blog is active.
    curl -fsSL https://plym.io/install | PLYM_DIR=acme-docs PLYM_PORT=8080 PLYM_VERBOSE=1 sh -s "Acme Docs" "docs@acme.com"

    What you get on disk

    plym/
    ├── .env                  # Port, database credentials, JWT secret, superuser
    ├── .plym-credentials     # Your admin email and password, mode 600
    ├── config.yaml           # Site name, template, colors, caching, robots, SEO
    ├── admin/                # Admin portal bundle, bind-mounted read-only
    ├── bin/                  # The plym CLI, copied onto your PATH during install
    ├── docker/Caddyfile      # Routing and content negotiation
    ├── docker-compose.yml
    ├── storage/
    │   ├── .generated/       # Rendered .html and .md pairs
    │   ├── _uploads/         # Media
    │   ├── backups/          # Scheduled database dumps
    │   ├── static/           # Logo, favicon, CSS bundle
    │   └── webfonts/         # Self-hosted fonts
    └── templates/            # Bundled default theme

    The plym CLI is installed to /usr/local/bin/plym, or to ~/.local/bin/plym when /usr/local/bin is not writable. This install becomes the active blog, so plym commands target it from any directory.

    Troubleshooting

    Message Cause and fix
    docker is required and not in PATH (or openssl, curl) Install the named tool and re-run.
    docker compose v2 is required You have the standalone docker-compose v1 binary. Install the Compose v2 plugin.
    Cannot connect to the Docker daemon macOS: open -a Docker and wait for it to finish starting. Linux: sudo systemctl start docker. If the daemon is already running, this is a permissions problem — sudo usermod -aG docker $USER, then log out and back in.
    Directory 'plym' already exists Remove it, or install elsewhere with PLYM_DIR=acme-docs.
    Could not pull plymio/plym:latest Check network access to Docker Hub. If the image is already in your local Docker cache the installer uses that copy and continues.
    Could not extract the plym files PLYM_IMAGE points at an image that is not a plym build. Unset it.
    Bind for 0.0.0.0:9173 failed: port is already allocated Neither lsof nor nc is installed, so the port probe was skipped. Install lsof, or set PLYM_PORT to a port you know is free.
    App did not come up The API did not answer /health within 120 seconds. Re-run with PLYM_VERBOSE=1, or read docker compose logs api in the install directory.
    Login failed for <email> (HTTP 401) A leftover Postgres volume from an earlier install still holds the old password. Run docker compose down -v in the install directory, delete the directory, and install again.
    Could not fetch admin <version> A warning, not a failure. The blog serves normally; the admin portal stays unavailable until plym admin update succeeds.
    plym: command not found The CLI landed in ~/.local/bin, which is not on your PATH. Add export PATH="$HOME/.local/bin:$PATH" to your shell profile.

    Any failure prints the underlying error above the summary line. Once the install directory exists, plym reinstall wipes the stack and its database volume and starts over.

    Uninstall

    cd plym
    docker compose down -v
    cd ..
    rm -rf plym
    sudo rm -f /usr/local/bin/plym /usr/local/bin/plym-lib.sh
    rm -rf ~/.config/plym

    down -v deletes the database volume. Your posts and media are gone and cannot be recovered.

    Frequently asked questions

    Can I run more than one blog on one host?
    Yes. Install again with a different PLYM_DIR; each install gets its own Compose project, port, and database volume. Switch between them with plym use <name>.
    Where do I change the port after installing?
    Edit PLYM_PORT in .env, then run docker compose up -d in the install directory.
    Can I install from a clone instead?
    Yes, for development. git clone https://github.com/plym-io/plym.git, copy .env.example to .env and config.yaml.example to config.yaml, then docker compose up --build. This path does not install the CLI and does not generate secrets for you.
    Does the installer need root?
    No. It falls back to ~/.local/bin for the CLI when /usr/local/bin is not writable. plym set url needs sudo later, because it writes reverse-proxy configuration.