Docker & compose
Prerequisites
- Docker and Docker Compose
- A
.envfile configured with all required environment variables — see Configuration
1. Create a directory for your deployment
mkdir my-links-deployment
cd my-links-deployment2. Create a docker-compose.yml
name: my-links
services:
postgres:
container_name: postgres
image: postgres:18
restart: always
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
healthcheck:
test: ['CMD-SHELL', 'pg_isready', '-U', '${DB_USER}']
volumes:
- postgres-volume:/var/lib/postgresql
ports:
- '${DB_PORT}:5432'
my-links:
container_name: my-links
image: sonny93/my-links:latest
restart: always
environment:
- DB_HOST=postgres
- HOST=0.0.0.0
- NODE_ENV=production
env_file:
- .env
depends_on:
postgres:
condition: service_healthy
ports:
- ${PORT}:3333
volumes:
- favicon-volume:/app/storage/favicons
volumes:
postgres-volume:
favicon-volume:favicon-volume holds the cached favicon images (see Configuration). Unlike postgres-volume, losing it isn't a data loss — the app re-downloads what it needs — but keeping it out of your backup strategy means a restore re-fetches every favicon from scratch instead of serving them immediately.
3. Create your .env
Use .env.example from the repository as a template, and see Configuration for what each variable does. It sits next to your docker-compose.yml, at the root of your deployment directory.
4. Start it
docker compose up -dThis pulls the image from Docker Hub, starts PostgreSQL, applies database migrations automatically, and starts the application in production mode — reachable on the port set in PORT (default 3333). Account maintenance runs alongside it in the same container, flagging inactive accounts and deleting expired ones once their grace period runs out — no separate setup needed.
Native deployment
If you would rather run it without Docker:
Node.js 24.14.0 (or compatible), pnpm, and PostgreSQL 18 installed and running.
Clone and install:
bashgit clone https://github.com/my-links/my-links.git cd my-links pnpm installCopy
.env.exampleto.envand configure it. Native runs expect it insideapps/webapp, unlike the Docker path above:bashcp .env.example apps/webapp/.envPoint
DB_*at your PostgreSQL instance, then apply migrations (everynode acecommand runs fromapps/webapp):bashcd apps/webapp node ace migration:runCompile the translation catalogs and build:
bashpnpm run compile node ace buildCopy
.envinto the build output and start it:bashcp .env build/ cd build pnpm run start
The application is reachable on the port set in PORT.
Account maintenance (flagging inactive accounts, deleting expired ones) and the favicon store's orphan purge are not automatic here — the Docker path gets them for free, scheduled inside the application itself, but a native deployment needs its own system cron calling, from build/:
node bin/console.js account:flag-inactive
node bin/console.js account:prune-deleted
node bin/console.js favicon:purge-orphans