Skip to content

PeakURL/containers

PeakURL

Official Docker image for PeakURL, a self-hosted URL shortener.

Quick reference

Use an exact version tag when you want a repeatable deployment.

What is PeakURL?

PeakURL lets you run your own branded short links with analytics, a dashboard, and a self-hosted PHP application you control.

This image packages the public PeakURL release archive and is intended for:

  • a simple Docker Compose deployment
  • a docker run deployment
  • a reverse-proxy setup behind Nginx, Apache, Traefik, or another SSL terminator

Pull the image:

docker pull peakurl/peakurl:latest

How to use this image

Docker Compose

Recommended layout on a server:

/var/www/sites/data/www/example.com/
├── compose.yaml
└── data/
    ├── mysql/
    └── peakurl/

Edit the values in compose.yaml before you start the stack:

  • set APACHE_SERVER_NAME to your real public short domain
  • review the 127.0.0.1:8080:80 port mapping and keep it on localhost if a host reverse proxy will forward traffic
  • set the MySQL credentials in the db service
  • keep the PeakURL installer defaults in the peakurl service aligned with the MySQL values
  • pin PEAKURL_IMAGE_TAG to an exact version if you want repeatable deploys

Example compose.yaml:

services:
    peakurl:
        # Pin an exact tag when you want repeatable deployments.
        image: docker.io/peakurl/peakurl:${PEAKURL_IMAGE_TAG:-latest}
        restart: unless-stopped
        environment:
            TZ: UTC
            # Change this to your real public short domain.
            APACHE_SERVER_NAME: example.com
            PEAKURL_INSTALL_DB_HOST_DEFAULT: db
            PEAKURL_INSTALL_DB_PORT_DEFAULT: "3306"
            # Keep these installer defaults aligned with the MySQL service below.
            PEAKURL_INSTALL_DB_NAME_DEFAULT: peakurl
            PEAKURL_INSTALL_DB_USER_DEFAULT: peakurl
            PEAKURL_INSTALL_DB_PASSWORD_DEFAULT: change-this-password
        ports:
            # Keep this on localhost if a host reverse proxy will forward traffic.
            # <Host IP>:<Host Port>:<Container Port>
            - "127.0.0.1:8080:80"
        volumes:
            # Keep the full PeakURL app tree beside the compose file.
            - "./data/peakurl:/var/www/html"
        depends_on:
            db:
                condition: service_healthy
        healthcheck:
            test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/ >/dev/null || exit 1"]
            interval: 30s
            timeout: 5s
            retries: 5
            start_period: 20s

    db:
        image: mysql:8.4
        restart: unless-stopped
        environment:
            # Change these database values before you deploy.
            MYSQL_DATABASE: peakurl
            MYSQL_USER: peakurl
            MYSQL_PASSWORD: change-this-password
            MYSQL_ROOT_PASSWORD: change-this-root-password
        command:
            - --character-set-server=utf8mb4
            - --collation-server=utf8mb4_unicode_ci
            - --skip-name-resolve
        volumes:
            # Keep database data beside the compose file by default.
            - "./data/mysql:/var/lib/mysql"
        healthcheck:
            test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -p$$MYSQL_ROOT_PASSWORD --silent"]
            interval: 10s
            timeout: 5s
            retries: 12
            start_period: 30s

Create the directories first:

mkdir -p data/peakurl data/mysql

Start it with:

docker compose up -d

Then open http://127.0.0.1:8080 and complete the installer.

If you already run Nginx or Apache on the host, keep the bind address on 127.0.0.1 and proxy your public domain to http://127.0.0.1:8080.

If you want to expose the container directly instead, publish a normal host port such as 8080:80.

This default layout keeps the app files and MySQL data beside the compose file, so each site folder stays self-contained and does not need a separate .env file.

On first start, the container copies the bundled PeakURL release into ./data/peakurl and then runs directly from that directory. This keeps the folder structure the same as the release ZIP.

Docker Run

Create a deployment folder first:

mkdir -p peakurl-stack/data/peakurl peakurl-stack/data/mysql
cd peakurl-stack

docker network create peakurl

Start MySQL:

docker run -d \
  --name peakurl-db \
  --network peakurl \
  -e MYSQL_DATABASE=peakurl \
  -e MYSQL_USER=peakurl \
  -e MYSQL_PASSWORD=change-this-password \
  -e MYSQL_ROOT_PASSWORD=change-this-root-password \
  -v "$PWD/data/mysql:/var/lib/mysql" \
  mysql:8.4 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
  --skip-name-resolve

Then start PeakURL:

docker run -d \
  --name peakurl \
  --network peakurl \
  -p 127.0.0.1:8080:80 \
  -e APACHE_SERVER_NAME=example.com \
  -e PEAKURL_INSTALL_DB_HOST_DEFAULT=peakurl-db \
  -e PEAKURL_INSTALL_DB_PORT_DEFAULT=3306 \
  -e PEAKURL_INSTALL_DB_NAME_DEFAULT=peakurl \
  -e PEAKURL_INSTALL_DB_USER_DEFAULT=peakurl \
  -e PEAKURL_INSTALL_DB_PASSWORD_DEFAULT=change-this-password \
  -v "$PWD/data/peakurl:/var/www/html" \
  peakurl/peakurl:latest

Then open http://127.0.0.1:8080 and finish the installer.

Reverse proxy and SSL

PeakURL serves plain HTTP inside the container. SSL should be terminated by your existing reverse proxy or load balancer.

Example host-side configs are included here:

Typical proxy target:

  • http://127.0.0.1:8080
  • or another localhost port you published for the container

Configuration

For Docker Compose, edit the values directly in compose.yaml.

The main values most users change are:

  • APACHE_SERVER_NAME
  • the published host port in ports
  • MYSQL_DATABASE
  • MYSQL_USER
  • MYSQL_PASSWORD
  • MYSQL_ROOT_PASSWORD
  • the matching PEAKURL_INSTALL_DB_* defaults

Persistent data

By default the Compose setup keeps data in local folders beside the compose file:

  • ./data/peakurl maps to /var/www/html and stores the full PeakURL app tree
  • ./data/mysql maps to /var/lib/mysql for the MySQL database

On first boot, ./data/peakurl is populated from the bundled release package, so files like content/languages/* stay exactly where the ZIP ships them.

If you prefer Docker-managed named volumes instead, you can replace those bind mounts in your own compose file.

Updating

For Docker Compose:

docker compose pull
docker compose up -d

For docker run, pull the new image and recreate the container with the same volume and environment settings.

When a new PeakURL release is published, a matching container image is published separately. Existing containers keep running their current image tag until you pull the new tag and recreate them.

Because this image stores the full app tree in ./data/peakurl, pulling a new image does not replace app files that already exist in that mounted directory. For a fresh app tree from a newer image, back up your site first, then recreate or clear ./data/peakurl before starting the updated container.

License

PeakURL is released under the MIT License.

About

Official Docker image for PeakURL

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors