doccano: A Self-Hosted Text Annotation Server for Classification, Tagging and Seq2seq
Open source annotation tool for machine learning practitioners.
At a glance
- What is it?
- doccano is an MIT-licensed Python annotation tool you deploy yourself and reach over HTTP. It covers text classification, sequence labeling and sequence to sequence work, and the README lists three install paths plus one-click AWS and Heroku templates. The judgement: it is a good fit when you want your labeled data to stay on your own infrastructure, and a poor fit if you need image, audio or video annotation.
- Who is it for?
- Adopt doccano if your labeling work is text and you want the server on your own machine or VPC, with PostgreSQL behind it and a REST API your pipeline can pull from. Do not adopt it if your data is images, audio or video, or if you need active learning built into the labeling loop.
- 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 154 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 September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What doccano Is For, and Who Ends Up Running It
The problem doccano addresses is narrow and concrete: turning raw text into labeled data without building an annotation interface first. The README describes it as an open-source text annotation tool for humans and names three task types it supports, text classification, sequence labeling, and sequence to sequence. The examples it gives for those are sentiment analysis, named entity recognition, and text summarization. That list is the scope. Anything outside text is out of scope.
The intended user is a machine learning practitioner who already has a corpus and needs labels on it. The README's own pitch is that you create a project, upload data, and start annotating, and that you can build a dataset in hours. The word humans in the project description matters: this is a tool for the people doing the labeling, not for the model consuming the result. The features list points the same way, with collaborative annotation, multi-language support, mobile support, and a dark theme sitting alongside the RESTful API.
That combination tells you the deployment shape. Someone on the team runs a server, other people log into it and label, and a script pulls the finished labels back out through the API. If your labeling is a solo effort on a laptop, the server is overhead you may not want. If it is a group of annotators spread across time zones, the collaborative annotation and mobile support features are the reason the project exists.
Two Processes, One Database and a Task Queue
The architecture visible in the README is a split between a web server and a background worker, both backed by a database. The pip path makes this explicit. You run doccano webserver --port 8000 in one terminal and doccano task in another. The README says the second command starts the task queue to handle file upload and download. That is the single most important operational detail in the document, because it means the web process alone is not enough. If the task queue is not running, the parts of the product that move files in and out will not complete.
Storage is configurable. By default SQLite 3 is used for the default database, and PostgreSQL is available through an extra dependency set. The Docker Compose path goes further and pulls in a message broker, with RabbitMQ settings in the .env file alongside the Postgres credentials. So the full production shape is webserver, worker, Postgres, and RabbitMQ, wired together by environment variables. The pip path is the same logical layout with fewer moving pieces.
The client side is a web application, and the repository topics list Nuxt, Nuxt.js, Vue and Vue.js alongside Python. The README does not describe the frontend architecture beyond that, so I will not speculate about how the annotation UI is structured internally. What the README does confirm is that the interface is reached over HTTP, whether that is 127.0.0.1:8000 from the pip path or port 80 from Docker Compose.
Three Install Paths and What Each One Costs You
The README offers pip, Docker, and Docker Compose, and the choice is really about how much of the stack you want to own.
The pip path needs Python 3.8 or later. You run pip install doccano, and if you want PostgreSQL instead of the default SQLite 3 you run pip install 'doccano[postgresql]' and set DATABASE_URL to a connection string of the form postgres://user:password@host:port/db?sslmode=disable. Then three commands in sequence: doccano init to initialize the database, doccano createuser --username admin --password pass to create a super user, and doccano webserver --port 8000 to start serving. A second terminal runs doccano task. The README points you at http://127.0.0.1:8000/.
The Docker path is a one-time container creation followed by repeated starts. The README's example creates a container named doccano with ADMIN_USERNAME, ADMIN_EMAIL and ADMIN_PASSWORD set as environment variables, a volume named doccano-db mounted at /data, and port 8000 published. You then run docker container start doccano and stop it with docker container stop doccano -t 5. The README states that all data created in the container persists across restarts, which is what the named volume is for. There is also a nightly tag for people who want unreleased features.
The Docker Compose path requires cloning the repository, and the README includes a Windows note: configure git with core.autocrlf=input or you may hit status code 127 errors when the services run. You create an .env file from docker/.env.example containing admin credentials, RabbitMQ credentials, and Postgres credentials, then run docker-compose -f docker/docker-compose.prod.yml --env-file .env up and reach the app at http://127.0.0.1/. Note the port difference: Compose serves on 80, the pip and single-container paths serve on 8000.
The one-click options are AWS via a CloudFormation template and Heroku via a deploy button. The README's footnote on AWS is worth reading before you click: an EC2 KeyPair cannot be created automatically, so you need one already in the region, and the README links a separate wiki page for HTTPS setup. There is no equivalent HTTPS instruction for the pip path.
Where doccano Stops Being the Right Tool
The clearest limitation is modality. Every task type the README names is text. There is no mention of image bounding boxes, audio segments, or video frames. Teams doing computer vision annotation are looking at a different class of tool, and no amount of configuration turns doccano into one.
The second limitation is operational and follows from the two-process design. The pip path asks you to keep a webserver and a task queue alive simultaneously. That is fine on a workstation and awkward on a shared server unless you put a process supervisor in front of it, and the README does not describe one. The Docker Compose path solves this by containerizing both, but it also adds RabbitMQ and Postgres to what you are now responsible for patching and backing up.
The third is release cadence. The recent releases show v1.8.5 in January 2026, v1.8.4 in July 2023, and v1.8.3 in December 2022. That is a long gap between the 2023 and 2026 releases. A team that pins to a version and expects regular security patches should read that history carefully before deciding. It does not mean the project is dead, since the last push date is 2026, but it does mean the upgrade path is not a steady stream.
Finally, the README does not describe authentication beyond the super user created at install time. It links to FAQ entries on creating a user, adding a user to a project, and changing a password, which suggests user management is handled per project, but the README itself does not cover SSO, LDAP, or role granularity. If your organization requires those, verify them against the documentation at doccano.github.io before you plan a rollout.
doccano Against Label Studio: Text-Only Versus Multi-Modal
The obvious alternative in this space is Label Studio, and the difference is scope rather than quality. Label Studio is built around a configurable labeling interface described in XML, and that interface language is what lets it cover images, audio, video, HTML and text within one deployment. doccano fixes its interface to the three text task types the README names, and you choose among them when you create a project.
That trade has two sides. Label Studio's flexibility means you spend time writing and debugging a labeling config before anyone can annotate. doccano's constraint means you pick a task type, upload data, and start, which is exactly the workflow the README describes. For a team whose entire labeling backlog is text, the constraint is a feature. For a team that will need to label a PDF page next quarter, it is a wall.
The second difference is deployment weight. Both are self-hosted, but doccano's pip path is genuinely small: one Python package, one init command, one user creation command, two long-running processes. That is a lower floor than a multi-modal tool typically offers. If you want the smallest possible footprint for a text-only job, the pip path is the argument for doccano.
There is also the question of what happens to the labels. doccano exposes a RESTful API, which is the documented way to get data in and out programmatically. The README does not specify export file formats, so if your training pipeline expects a particular JSON schema, check the documentation before assuming the export matches it.
Maintenance, Upgrades and the MIT Licence
Because doccano is self-hosted, the upgrade cost falls on you. The pip path upgrades with a new pip install, but you still own the database migration, which the doccano init command implies is part of the lifecycle. The Docker path upgrades by pulling a new image tag, and the README's nightly tag is a reminder that tags are not all equivalent: nightly tracks unreleased work, and the versioned tags are the ones with a release date attached.
The Compose path has the widest upgrade surface. A version bump may touch the application image, the Postgres image, and the RabbitMQ image, and the .env file holds credentials for two of those. Backups are your responsibility in every path, and the README only tells you that the doccano-db volume persists data across container restarts. That is a statement about persistence, not about backup.
The licence is MIT, which is permissive and places few obligations on how you deploy or redistribute the software. That is a genuine advantage for teams that want to embed an annotation tool in an internal platform. It is not legal advice, and if your organization has specific compliance requirements around the dependencies you ship, review the full dependency tree rather than the top-level licence alone.
One more maintenance note from the README: the project is under continuous development and the contribution path is fork, add a feature or fix a bug, then file a pull request. If you need a feature that does not exist, the documented route is to file an issue describing the request. There is no commercial support tier mentioned anywhere in the material.
What to Check Before You Commit
The decision comes down to three questions you can answer from the README plus a short trial.
Is your data text? If yes, doccano is in scope. If you have images, audio or video, stop here.
Do you want the server on your own infrastructure? The pip path and the Docker path both keep everything local, and the Docker Compose path gives you the fuller production stack with Postgres and RabbitMQ. The AWS and Heroku templates exist for teams that would rather not run the boxes, but the AWS footnote about the pre-existing EC2 KeyPair is a real prerequisite, and the README defers HTTPS on AWS to a separate wiki page.
Can you operate two processes? The doccano webserver and doccano task split is the design, not a suggestion, and file upload and download depend on the second one. If nobody on the team will own that, use the Compose path where both are containerized.
The thing to verify first, before any of that, is the export format. The README promises a RESTful API but does not document the shape of what comes back, and the whole point of annotating is feeding a training pipeline. Pull one project's worth of labels through the API on a throwaway deployment and confirm the schema matches what your code expects. That single check will tell you more about fit than any feature list.
Editorial conclusion
Adopt doccano if your labeling work is text and you want the server on your own machine or VPC, with PostgreSQL behind it and a REST API your pipeline can pull from. Do not adopt it if your data is images, audio or video, or if you need active learning built into the labeling loop. Before committing, verify three things on your own deployment: that the task queue process is running, because file upload and download depend on it; that your database choice matches the install path you picked, since the default is SQLite 3 and PostgreSQL requires the extra dependency set; and that your import format matches the task type, because classification, sequence labeling and sequence to sequence expect different file structures. The MIT licence and the absence of a hosted control plane mean the upgrade clock is yours to set, not a vendor's.
Community notes