You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
James Harmison 3c6adb34e3
Added notes on backups and upgrades.
6 months ago
env Streamline setup process (#3) 6 months ago
files Streamline setup process (#3) 6 months ago
podman Cleared up some language around sudo. 6 months ago
.drone.yml Revert "Added cache option" 6 months ago
.gitignore Cleaned whitespace 6 months ago
Dockerfile Fix drone workflow 6 months ago
LICENSE Added license 7 months ago Added notes on backups and upgrades. 6 months ago Streamline setup process (#3) 6 months ago
docker-compose.yml Initial commit 7 months ago

Akaunting Docker Image

Build Status

Builds from main are pushed to Harbor

You can pull the latest image with docker pull


This repository, and the images built from it, are unofficial and are not affiliated with the Akaunting project or Akaunting Technology Inc. It is the belief of the author that this FOSS repository meets the criteria for Automatic Approval under the Akaunting trademark terms.

Akaunting is online, open source and free accounting software built with modern technologies. Track your income and expenses with ease. For more information on Akaunting, please visit the official website.


  1. One of:
    • docker-compose
    • docker
    • podman
  2. Some other reverse proxy for TLS termination. I use HAProxy for TLS termination, because it enables me to load balance to the applications I choose to cluster, and I can use Let'sEncrypt wildcard certificates for the HAProxy frontend. See Reverse proxying for TLS termination for more information.
  3. Your own cache, with a supported Laravel extension, if you need to scale to lots of users. From what I can see in the Laravel documentation, configuration with Redis looks very straightforward. You should be able to use my images for a more advanced configuration like that on your own if you need it. If that is not the case, please email me.


The following sections are broken down by tooling. You should look at the section that matches the deployment environment you're expecting.


git clone
cd akaunting
cp env/db.env.example env/db.env
vi env/db.env # and set things
cp env/run.env.example env/run.env
vi env/run.env # and set things

docker-compose up -d -e AKAUNTING_SETUP=true

Then head to HTTP at port 8080 on the docker-compose hostand finish configuring your Akaunting company through the interactive wizard.

After setup is complete, bring the containers down before bringing them back up without the setup variable.

docker-compose down -v
docker-compose up -d

Included is a watchtower container. This will automatically pull updates for the mariadb and unofficial Akaunting images daily, restarting the containers with the new images when there has been an update.


You can manually start the container images with docker, and customize them as needed, without even downloading the repository.

docker run -d -v akaunting-db:/var/lib/mysql \
    -e MYSQL_DATABASE=akaunting \
    -e MYSQL_USER=admin \
    -e MYSQL_PASSWORD=akaunting_password \
    --name akaunting-db mariadb:latest
docker run --rm -d -v akaunting-data:/var/www/html/storage \
    -p 8080:80 \
    -e APP_URL= \
    -e LOCALE=en-US \
    -e DB_HOST= \
    -e DB_DATABASE=akaunting \
    -e DB_USERNAME=admin \
    -e DB_PASSWORD=akaunting_password \
    -e DB_PREFIX=qwe_ \
    -e COMPANY_NAME="My Company" \
    -e COMPANY_EMAIL="" \
    -e ADMIN_EMAIL="" \
    -e ADMIN_PASSWORD="password" \
    --name akaunting --setup

At this point, open a browser and access the interface via HTTP at port 8080 and finish configuring your Akaunting company through the interactive wizard. After setup is complete, bring the akaunting container down and start a new one without the --setup parameter.

docker stop akaunting
docker run --rm -d -v akaunting-data:/var/www/html/storage \
    -p 8080:80 \
    -e APP_URL= \
    -e LOCALE=en-US \
    -e DB_HOST= \
    -e DB_DATABASE=akaunting \
    -e DB_USERNAME=admin \
    -e DB_PASSWORD=akaunting_password \
    -e DB_PREFIX=qwe_ \
    --name akaunting

Note that the DB_PREFIX variable should stay the same in between runs, as it is randomly generated if not provided and the table names will not align, causing errors. Also note that several variables have been left off for this run, because they are not needed for non-setup runs.


Please refer to podman/ for more information on provided podman scripts. There are a couple of possible configurations.

The use of the podman-docker package for your distribution or a simple alias docker=podman in your ~/.bashrc should enable you to line-for-line copy the docker instructions above, except that you must also provide an exposed port for mariadb and ensure that you configure the Akaunting server to appropriately reach the Host IP or hostname to hit the port forward. Please see this blog post for more information on rootless networking with podman.

Use of the scripts from the podman directory will create pods, instead of containers, and you will not have to expose the database and can refer to it by

Backup and restore

I use something like the following commands to make backups for my deployment (I use podman, and I relabel for SELinux shared usage of volumes):

mkdir -p ~/backups
for volume in akaunting-data akaunting-db; do
    docker run --rm -v $volume:/volume -v ~/backups:/backups alpine tar cvzf /backups/$volume-$(date +%Y-%m-%d).tgz -C /volume ./

In order to restore those backups, you would run something like:

backup=2021-01-26 # you should select the backup you want to restore here
for volume in akaunting-data akaunting-db; do
    docker run --rm -v $volume:/volume -v ~/backups:/backups alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar xvzf /backups/$volume-$backup.tgz -C /volume"

A note on upgrades

The upgrade between 2.0.26 and 2.1.0 broke some things due to a Laravel version migration in Akaunting. In order to fix this, I ran something like the following:

docker exec -it akaunting bash

Then, inside the container, ran the following:

php artisan view:clear

I can see the possibility that future version migrations might require something like:

php artisan migrate --force

I do not intend on baking migration logic into the container image. In my view, the application containers should be dumb and naive. An upgrade between versions that requires intervention would best be encapsulated in something like a Kubernetes Operator, rather than adding to the complexity of the application image. If you use these images in production, I would recommend a testing environment that draws automatic updates and validates the steps required to migrate between versions, and pinned version number tags for your production image. Migrating your production version would then require manual intervention and enable you to take the manual steps necessary to complete the migration.

Building your own

If you don't want to pull my image, or you've made changes to the code and would like to build your own, is provided at the repository root. You can run it with the -h option to see the provided options. You could modify docker-compose.yml or podman/ to point to your own image if you would like to use the rest of the automation provided here.

Reverse proxying for TLS termination

No configuration has been provided for TLS termination, and none will be given in this repository. The container image accepts connections from any proxy, and recognizes the host from HTTP requests via the APP_URL environment variable.

Googling "letsencrypt haproxy" provides me with a number of articles with decent instructions on how to set up HAProxy and certbot to automatically renew certificates served. Some extra keywords, like wildcard, give good results to show you how to really take advantage of HAProxy's simple configuration and LetsEncrypt's free wildcard TLS certificates. If you really like nginx, an nginx configuration that stitches together the elements of load balancing, reverse proxying, and Let'sEncrypt can meet the same need. So can Apache, or a number of other webservers. The world is your oyster.

A robust TLS termination and load-balancing setup should outperform, and be easier to maintain than, lots of little nginx containers everywhere. I don't believe they're the best fit for this use case. Running Akaunting in a container makes the most sense if you're running lots of services on fewer hosts, and for that use case you should use a load-balancing reverse proxy for TLS termination.


Right now, the only built language is US English. I was building every supported language, but that was causing CI timeouts after a full hour on a single-threaded machine. If you would like a language added to the images, please just send me an email.


I am currently running Akaunting for multiple small companies from my infrastructure. I intend on continuing to maintain the images if anything breaks or changes are required to enable functionality that I would like, but this is entirely at my own will and I am under no obligation to do so. If you don't want to maintain a fork of this repository on the SCM platform of your choosing (you can clone it from here over HTTPS without an account and add your own remote), feel free to shoot me an email asking for me to enable or fix something. You can reasonably count on me to keep this image working, but I make no guarantees about that claim, or any claims of the suitability of my image now or in the future.


All code used to build my unofficial container image of the Akaunting software is licensed under the BSD 2-clause license. A copy of the text of that license is included in this repository. Akaunting is licensed under the GNU GPL v3 License, and copies of that license are included in images produced by this repository at /var/www/html/LICENSE.txt.