Self-hosted service
andrii-kryvoviaz/slink avatar
andrii-kryvoviaz/slink

Slink: a self-hosted image sharing platform built on Symfony and SvelteKit

Self-hosted image sharing service

1,592 stars48 forksPHPAGPL-3.0

At a glance

What is it?
Slink is a PHP and SvelteKit application for running your own private image host, with password-protected shares, expiring links, collections and OIDC login. It is aimed at people who want image sharing off third-party services, and it ships as a Docker image rather than a hosted product.
Who is it for?
Adopt Slink if you want image sharing you control and you are comfortable running a Docker Compose stack with a database and a storage backend. Skip it if you need a managed service, a mobile app, or a host that does not require you to think about SMB or S3 credentials.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Slink is for, and who it is not for

Slink is a self-hosted image sharing service. The README frames the problem directly: sharing images with friends, family and colleagues inside a private environment instead of through a third-party service. Three audiences are named. Artists who want a community-focused place to show work. Developers who need to host and share screenshots for GitHub, portfolios or blogs. And anyone who wants control over image privacy and hosting.

The design assumption behind that is ownership. Shares are private by default, and the README states that access is granted only to whoever holds the link. That is a different default from public image hosts, where an upload is reachable unless you change a setting. If your workflow depends on images being discoverable, Slink's Explore page is the opt-in path, and it only shows images other users have made publicly visible.

The people this is wrong for are equally clear. Anyone who wants a hosted service with no server to run is not the audience. Neither is a team that needs image editing, since Slink compresses and stores images but the README describes no editor. The feature list is about sharing, access control, organization and administration, not about post-processing.

How the application is put together

The stack is split in two. The API is a Symfony application in PHP, and the client is a SvelteKit application. The repository layout reflects that: there is a services/ directory, a docker/ directory, a Makefile, and a docker-bake.hcl file driving image builds. The Makefile targets reference services/api and services/client separately, so the backend and frontend are independently buildable artifacts.

The Makefile also tells you how the pieces are wired at runtime. The production target builds with buildx bake and then runs docker compose with two files: docker/docker-compose.yaml as the base and docker/docker-compose.prod.yaml as the production overlay. The same base file is reused for development with docker/docker-compose.dev.yaml, for host development with docker/docker-compose.dev-host.yaml, and for end-to-end tests with docker/docker-compose.e2e.yaml. That layered compose pattern means the base file holds the shared service definitions and each overlay changes what it needs to.

One concrete detail from the test target: the health check polls http://localhost:8080/api/health, and the end-to-end run points the client at http://localhost:3100 and the API at http://localhost:8180. Those are the ports the test harness uses, and they give you a sense of how the client and API are separated in the compose network. The README does not document the production port mapping, so treat those numbers as test-environment values rather than deployment defaults.

Storage is pluggable. The README lists local, SMB and AWS S3 as supported storage providers, and the repository has a storage-integration test group with an SMB contract test that runs against a Samba container. That is a strong signal that SMB is treated as a first-class backend rather than an afterthought, because it is exercised in the project's own test targets.

Installing Slink and uploading a first image

The README does not contain step-by-step install instructions. It links to a quick start page at docs.slinkapp.io/getting-started/02-quick-start/ and a configuration page for environment variables. The repository itself shows the intended route: build the images and bring up the compose stack.

The Makefile's run target does exactly that. It builds the production image with buildx bake and then starts the stack under the project name slink.

bash
make run

That expands to a build followed by `docker compose -p slink -f docker/docker-compose.yaml -f docker/docker-compose.prod.yaml up -d`. Before running it you will need a Docker installation with buildx available, since the target calls `docker buildx bake`. The README does not list minimum Docker or Compose versions, so check the compose file in docker/ for the syntax it expects.

For a development setup the Makefile has a separate target that attaches to the container so you can see logs.

bash
make run-dev

This builds the dev image and brings up the stack with docker/docker-compose.dev.yaml, then runs `docker attach slink`. If you want the host-mounted variant instead, the Makefile defines run-dev-host, which checks whether the slink service is already running before building and starting it.

Once the stack is up, the first real use is an upload. Sign up with email and password, or use one of the OIDC providers the README lists (Google, Authentik, Keycloak, Authelia, Pocket ID, or a custom provider). If the administrator has enabled user approval, an account may need approval before it can upload. After that, upload an image, open the share management page, and set an expiration or a password on the share. The README states these are per-share options, not global settings, so the defaults remain private with link-only access.

Access control is the part worth judging Slink on

The feature list is long, but the access control model is what separates Slink from a generic file drop. Four mechanisms sit on top of each share: private by default, an optional password, an optional expiration that auto-revokes the share, and a management page where shares can be listed, edited, published or revoked. Collections group images so an entire set goes out under one link.

The expiration behavior deserves attention before you rely on it. The README says a share auto-revokes after a chosen time. It does not say whether revocation deletes the underlying image, whether an expired link returns an error or a not-found page, or whether an administrator can restore an expired share. Those are the questions to answer from the documentation or the code if your use case involves sensitive material with a retention requirement.

URL shortening is offered as a separate feature from sharing. That is a useful distinction: a short image URL and a private share are different objects, and the README does not describe how they interact. If you plan to hand out short links, confirm whether a shortened URL inherits the password and expiration of the share it points to.

On the identity side, Slink supports email and password plus SSO through OIDC, and it can require approval before a user uploads. Guest upload is also available, which allows unauthenticated users to upload without accounts. Those two settings pull in opposite directions, and the README does not describe guardrails that reconcile them. If you enable guest upload, the moderation tools are the backstop, and the README does list image moderation and full administrative control over visibility.

Where Slink will frustrate you

Documentation is the weakest part of the project as it stands. The README is a feature list with links, not a manual. Installation, environment variables, storage provider configuration and security considerations all live on docs.slinkapp.io, and the README gives no fallback if a page is missing or out of date. For a self-hosted service that you are expected to operate, the gap between the feature list and an operational runbook is real work you will do yourself.

Storage is the second constraint. Local, SMB and AWS S3 are the three providers named. There is no mention of Google Cloud Storage, Azure Blob Storage, Backblaze B2 or any S3-compatible endpoint beyond AWS S3 itself. If your infrastructure is not one of those three, you are either adapting an S3-compatible provider without a documented guarantee or waiting for support.

HEIC and TIFF support carries an asterisk in the README's format list. The asterisk is not explained in the README text, so treat those two formats as conditional until you read the note on the documentation site. The other listed formats (PNG, JPG, WEBP, SVG, BMP, ICO, GIF, AVIF) have no such marker.

Finally, the AGPL-3.0 licence is a genuine consideration if you plan to modify Slink and expose it to users over a network. That is a question for your own legal review, not something the README resolves.

How Slink differs from a plain S3 bucket plus a CDN

The obvious alternative is putting images in an object store and serving them through a CDN or a signed URL. That approach is simpler to operate and cheaper to run at low volume, and it needs no application server at all. The difference in approach is where the logic lives. With a bucket, access control is a property of the URL signature: expiry and permission are encoded in the link, and there is no user model, no share management page, no collections and no comments.

Slink moves that logic into the application. Shares are records with an owner, an optional password and an optional expiration, and they can be revoked after the fact. That matters when you need to un-share something. A signed URL cannot be recalled before it expires unless you rotate the signing key, while the README describes a dedicated page for revoking a share. The trade-off is that you now run a PHP application, a database and a frontend, and you own the upgrades.

A second alternative is a public image host with an API. Those remove the operational burden entirely and usually have better delivery networks. They also put your images under someone else's terms and retention policy, which is the exact problem the README opens with. Slink is the answer to that problem, and the cost of the answer is the server you now maintain.

Maintenance, releases and licence

The last push to the repository was on 2026-09-09, and the most recent release is v1.13.1 from 2026-08-25. Releases before that are v1.13.0 on 2026-08-01 and v1.12.3 on 2026-07-15. The cadence in that window is roughly one release a month, which suggests the project is being worked on, but the only maintenance facts available are the push date and the release tags. There is no published support policy or long-term support branch in the README.

Upgrade cost is dominated by the deployment model. The Makefile rebuilds images with buildx bake and recreates containers with docker compose, so an upgrade is a rebuild and a restart. The README does not document rollback, database migration behavior, or whether a downgrade is supported. If you run Slink in production, the migration path between minor versions is something to verify from the release notes or the repository before you pull a new tag.

Licensing is AGPL-3.0. For self-hosting your own instance, that is straightforward. For anyone who wants to modify Slink and offer it as a network service to others, the copyleft obligations are the part to read carefully with a lawyer. The README says only that the project is licensed under AGPLv3 and points to the LICENSE file.

Editorial conclusion

Adopt Slink if you want image sharing you control and you are comfortable running a Docker Compose stack with a database and a storage backend. Skip it if you need a managed service, a mobile app, or a host that does not require you to think about SMB or S3 credentials. Before committing, read the environment variable and storage provider pages in the docs, confirm the HEIC and TIFF support is not marked as conditional, and check that your reverse proxy handles the client and API ports the compose files expose.

Frequently asked questions

What is Slink?

Slink is a self-hosted image sharing platform built with Symfony and SvelteKit. It lets you share images privately, with optional passwords and expirations, without relying on a third-party service.

What image formats does Slink support?

The README lists PNG, JPG, WEBP, SVG, BMP, ICO, GIF, AVIF, HEIC and TIFF. HEIC and TIFF are marked with an asterisk that the README does not explain, so check the documentation before relying on those two.

What storage providers can Slink use?

The README names local storage, SMB and AWS S3. No other object storage backends are listed.

Does Slink support single sign-on?

Yes. The README lists SSO and OIDC support with Google, Authentik, Keycloak, Authelia, Pocket ID and custom OIDC providers, alongside email and password login.

How do I install Slink?

The README does not include install steps. It links to docs.slinkapp.io for a quick start guide, and the repository Makefile shows a run target that builds images with buildx bake and starts the stack with docker compose.

Official sources

  1. andrii-kryvoviaz/slink on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/andrii-kryvoviaz-slink.svg)](https://hysenlabs.com/projects/andrii-kryvoviaz-slink)