dpaste: a pastebin you can run yourself, or mount in Django
The Django project driving dpaste.org
At a glance
- What is it?
- dpaste is the Django project behind dpaste.org, a pastebin that can run as a standalone project or be installed into an existing Django application. Its Docker build compiles the client assets in a Node stage and serves the app with pyuwsgi, and the newest release tag still predates the recent commits by years.
- Who is it for?
- dpaste suits a team that wants paste functionality under its own domain, with the option to embed the application in an existing Django project rather than run a separate service. It does not suit a team that wants a supported release cadence, because the newest tag is v3.8 from 2023 while commits continued to 2026-10-21, and it does not suit a deployment without Python and Node build stages available.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A pastebin that is also a reusable Django application
dpaste is a pastebin application written in Python using the Django framework, and it is the project that drives dpaste.org, where a live installation is available. The documentation lives separately at docs.dpaste.org.
The architectural decision that shapes everything else is stated in the README: the project is intended to run standalone as any regular Django project, but it is also possible to install it into an existing project as a typical Django application. Those are two different products sharing one codebase. The standalone form is what the Docker image and the compose file serve, with its own static assets and its own database. The embeddable form is what you want if your organisation already runs Django and already has users, because then the paste system can live inside an existing application rather than beside it.
That dual nature is the reason to look at this project at all. Plenty of paste software exists as a service you send text to. What is unusual here is that the same code can become a Django app inside your own product, with your own URLs and your own authentication.
The Docker build compiles assets in Node, then serves with pyuwsgi
The Dockerfile has two stages. The first builds the static assets from a node:lts image, and the second builds the Python application from python:3.10 and copies the compiled assets across.
FROM node:lts as staticfiles
ARG BUILD_EXTRAS=production
WORKDIR /app
# Install the JS dependencies
COPY package.json package-lock.json Makefile ./
RUN if [ "$BUILD_EXTRAS" = "dev" ] ; then npm install --ignore-scripts ; else npm ci --ignore-scripts ; fiThe client sources are then copied in and the two asset bundles are produced.
COPY client ./client
RUN mkdir -p dpaste/static
RUN make css
RUN make jsThe Python stage installs pip, copies the built static files in from the first stage, installs the project as an editable package with the extras selected by the same BUILD_EXTRAS argument, and collects the static files.
RUN pip install -e .[${BUILD_EXTRAS}]
# Copy the rest of the application code
COPY . .
# Collect all static files once.
RUN ./manage.py collectstatic --noinputThe runtime command applies migrations and then starts the application under pyuwsgi, with the port taken from the PORT environment variable, and the image exposes that port.
CMD ./manage.py migrate --noinput && ./manage.py pyuwsgi --http=:${PORT} --logger file:/var/log/uwsgi.log
EXPOSE ${PORT}The Dockerfile comment is explicit that pyuwsgi is the default for production and that docker compose overrides it for development.
Compose runs the dev server and a separate migration job
The compose file at the repository root defines three services and two named volumes. The app service is a development setup: it maps port 8000, mounts the source tree into the container, and runs the Django development server.
environment:
STATIC_ROOT: /collectstatic
DATABASE_URL: sqlite:////db/dpaste.sqlite
PORT: 8000
volumes:
- .:/app:delegated
- data_collectstatic:/collectstatic
- data_db:/db
ports:
- "8000:8000"
command: ./manage.py runserver 0:8000Note that the database is SQLite inside a named volume, reachable at the path in DATABASE_URL. That is a development arrangement, not something to copy into production unchanged.
The third service exists because migrations are a job rather than a startup step.
migration:
image: app
command: ./manage.py migrate --noinput
volumes:
- .:/app:delegated
- data_db:/dbRunning migrate as its own service means the migration completes against the same database volume before the app serves traffic, and the noinput flag keeps the command from stopping for a prompt inside a container. There is also a minimal.docker-compose.yml at the repository root for a smaller setup, and a .deploystack/ directory for deployment configuration.
Client assets are Sass and a legacy minifier
The root package.json is small and old fashioned, and it tells you what the front end build looks like.
"name": "dpaste",
"version": "3.0.0",
"repository": "https://github.com/DarrenOfficial/dpaste",
"license": "MIT",
"dependencies": {
"sass": "1.52.1",
"uglify-es": "3.3.10"
}Two dependencies, Sass for the styles and uglify-es for minification, driven by the make css and make js targets that the Dockerfile calls. The Makefile is copied into the Node stage together with package.json and package-lock.json so that the asset build can run before any Python code is copied, and the comment in the Dockerfile says exactly that: the Python application does not need to exist yet.
There is a version skew here worth noticing. The Python package version and the JavaScript package version are tracked separately, since the root package.json says 3.0.0 while the Python release tags are at v3.8. The client/ directory holds the front end sources, dpaste/static/ is where the compiled output lands, and a .node-version file pins the Node version the project expects.
Minimum versions and the shape of the Python package
The README states the floor plainly: dpaste requires at a minimum Python 3.9 and Django 3.2. That is a compatibility contract, and it is also the number to check first when you are deploying, because a newer Django release may not satisfy it.
The Python packaging itself is minimal. setup.py contains only a shebang, an import of setup from setuptools, and a call to setup, with everything configured in setup.cfg rather than in the script. The repository also carries MANIFEST.in for the source distribution, tox.ini for test environments, a .travis.yml for continuous integration, and setup.cfg with the packaging metadata.
The client/ and dpaste/ directories are siblings at the root, and manage.py sits next to them, so the layout is the conventional Django one with the front end sources kept outside the Python package. For the embeddable installation path, that separation is what allows the assets to be rebuilt or replaced without touching the Python application.
Release tags have not moved since 2023
The release list is the thing to look at before adopting this. The most recent tags are v3.6 from 2022-03-27, v3.7 from 2022-06-03 and v3.8 from 2023-11-18, while the last push to the repository was on 2026-10-21.
So the tags are stale by nearly three years and the working tree has moved well past them. The repository is not archived, and the work is visible in the tooling: renovate.json for dependency updates, a Python CI workflow, a Docker Image CI workflow that publishes to the Docker Hub image darrenofficial/dpaste, and a code quality badge through Codacy.
The practical consequence is that there is no upgrade path by tag. If you deploy the Docker image, you are deploying whatever the working tree contains at build time, and if you deploy from pip you would be installing a release from 2023 with a Django 3.2 era dependency set. Neither is necessarily wrong for a self-hosted utility, but it does mean you own the upgrade, and the compatibility floor in the README may lag what the code now expects.
Self hosting a pastebin versus using a public one
The alternative is to use a hosted paste service and accept someone else's retention policy, URL scheme and terms. The difference in approach is not cosmetic.
A public service gives you a short link immediately and nothing to operate. Self hosted dpaste gives you control over where the data lives, how long it is kept, and what the URLs look like, which matters when the pasted content is internal: a link on your own domain does not tell a third party that your engineers are discussing a particular incident. The embeddable path goes further, because the paste can live inside an application your users are already logged into, with your own authentication and your own navigation around it.
What you take on is the whole operational surface. TLS termination, database backups, disk growth, abuse handling and version upgrades all land on you, and the abuse part is the one people underestimate, because a paste site that accepts anonymous posts is a target and a moderation policy is work rather than configuration. The repository does not document any of that, so treat it as engineering you will have to plan for rather than a solved problem.
Editorial conclusion
dpaste suits a team that wants paste functionality under its own domain, with the option to embed the application in an existing Django project rather than run a separate service. It does not suit a team that wants a supported release cadence, because the newest tag is v3.8 from 2023 while commits continued to 2026-10-21, and it does not suit a deployment without Python and Node build stages available. Verify first which commit you are running, since the Docker image builds from the working tree rather than from a tagged release, and confirm that the Python 3.9 and Django 3.2 minimums match your environment.
Frequently asked questions
What are the minimum Python and Django versions for dpaste?
The README states that dpaste requires at a minimum Python 3.9 and Django 3.2.
How do I run dpaste with Docker Compose?
The repository ships docker-compose.yml with three services: a staticfiles build, an app service that runs ./manage.py runserver 0:8000 with port 8000 mapped, and a migration service that runs ./manage.py migrate --noinput against the same database volume.
Can dpaste be used inside an existing Django project?
Yes. The README states the project is intended to run standalone as a regular Django project, but it is also possible to install it into an existing project as a typical Django application.
Which web server does the dpaste Docker image run?
The Dockerfile comment says it runs pyuwsgi by default as a production ready server, with the command ./manage.py migrate --noinput && ./manage.py pyuwsgi --http=:${PORT}. The compose file overrides that with the regular Django development server for development.
Official sources
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.
[](https://hysenlabs.com/projects/darrenofficial-dpaste)Was this useful?