<!--
  canonical-url: https://www.avonture.be/blog/docker-limesurvey
  published:     2024-02-01
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Install LimeSurvey using Docker

> Learn to install LimeSurvey quickly and easily using Docker Compose. A complete guide on setup, data persistence with volumes, and running specific versions.

---
![Install LimeSurvey using Docker](/img/v2/limesurvey.webp)

**TL;DR**

This article shows how to spin up LimeSurvey, an open-source survey tool, using Docker Compose with the `martialblog/docker-limesurvey` image. It covers a minimal setup to get the site running at `http://localhost:8080`, adding volumes so your surveys and configuration survive container restarts, and pinning both LimeSurvey and MySQL to specific versions when you need to reproduce an older production environment locally.

LimeSurvey is an open-source survey tool that allows users to create and conduct surveys online. It is a powerful and intuitive tool that can be used by everyone.

Once again, it's easy to play with it and create a sandbox site to take a look at all its features; thanks to Docker.

*Two things this `compose.yaml` relies on and that are explained elsewhere on this blog: [volumes](/blog/docker-volumes), so your surveys survive a container restart, and [healthchecks](/blog/docker-healthy), to make LimeSurvey wait until MySQL really accepts connections.*

To do this, we'll use the <https://github.com/martialblog/docker-limesurvey> Docker image.

## LimeSurvey, running in two minutes

One `compose.yaml` file, one `docker compose up --detach`, and here is what waits for you on `http://localhost:`8080`/admin`:

> Screenshot — http\://localhost:8080/admin
>
> ![LimeSurvey dashboard](./images/dashboard.webp)

A full LimeSurvey installation — survey list, participants, statistics — running on your machine, with nothing installed except Docker. Let's build it.

## Let's play

Please start a Linux shell and run `mkdir -p /tmp/limesurvey && cd $_` to create a folder called `limesurvey` in your Linux temporary folder and jump in it.

Please then create a `compose.yaml` file in that folder with this content:

**compose.yaml**

```yaml
name: limesurvey

services:
  limesurvey-app:
    image: docker.io/martialblog/limesurvey:latest
    container_name: limesurvey-app
    restart: always
    environment:
      - DB_TYPE=mysql
      - DB_HOST=limesurvey-db
      - DB_NAME=limesurvey
      - DB_USERNAME=admin
      - DB_PASSWORD=admin
      - ADMIN_USER=admin
      - ADMIN_PASSWORD=admin
      - ADMIN_NAME=admin
      - ADMIN_EMAIL=admin@example.com
    ports:
      - 8080:8080
    depends_on:
      limesurvey-db:
        condition: service_healthy

  limesurvey-db:
    image: docker.io/mysql:8.4
    container_name: limesurvey-db
    environment:
      - MYSQL_USER=admin
      - MYSQL_PASSWORD=admin
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=limesurvey
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 10s
      retries: 10
```

Now, simply run the following command to download (only the first time) required images (LimeSurvey and MySQL) and create the two containers:

```bash
$ docker compose up --detach
```

Once everything has been downloaded and started, you can check you have two containers by running the following command:

```bash
$ docker container list

[...] IMAGE                         [...] NAMES
[...] martialblog/limesurvey:latest [...] limesurvey-app
[...] mysql:8.4                     [...] limesurvey-db
```

> **The output above has been simplified:**
>
> For clarity, the output of `docker container list` has been simplified here above; not all columns were mentioned in the article.

The `service_healthy` condition in the compose file ensures LimeSurvey won't start until MySQL is ready, which eliminates the connectivity errors you might have read about in older tutorials. Still, please wait **one or two minutes** (depending on your machine) for LimeSurvey to initialize its database tables.

Go to `http://localhost:`8080 and if you see `ERR_CONNECTION_REFUSED`, wait a little longer and refresh. When it's ready, you should see the default LimeSurvey welcome page.

> **Look at the logs:**
>
> If you have been waiting a long time and something seems wrong, run `docker compose logs -f` to inspect the logs. You should see `[core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'` when LimeSurvey is ready, meaning the web server is up and accepting connections.
>
> Press `CTRL`-`C` to stop following the logs.

## First login

When LimeSurvey is ready, you'll see the following page on `http://localhost:`8080:

> Screenshot — http\://localhost:8080
>
> ![LimeSurvey welcome page](./images/homepage.webp)

Go to `http://localhost:`8080`/admin` to start the administration interface. The credentials to use are `admin` / `admin` (as defined in the `compose.yaml` file, see variables `ADMIN_USER` and `ADMIN_PASSWORD`).

> Screenshot — http\://localhost:8080/admin
>
> ![LimeSurvey administration page](./images/admin.webp)

Once logged in, you land on the dashboard shown at the beginning of this article, and you're ready to play with LimeSurvey on your machine.

## Using volumes

The `compose.yaml` file provided above didn't use any volumes: when you stop running containers, your work will be lost and LimeSurvey will be restarted without any configuration / surveys just like a full reset.

Perhaps, if you want to test LimeSurvey over several days and keep your configuration items, your surveys, then you will want to keep your work. To do this, you need to use volumes.

Here is an updated `compose.yaml` file to ask Docker to use self-managed volumes.

**compose.yaml**

```yaml
name: limesurvey

services:
  limesurvey-app:
    image: docker.io/martialblog/limesurvey:latest
    container_name: limesurvey-app
    restart: always
    environment:
      - DB_TYPE=mysql
      - DB_HOST=limesurvey-db
      - DB_NAME=limesurvey
      - DB_USERNAME=admin
      - DB_PASSWORD=admin
      - ADMIN_USER=admin
      - ADMIN_PASSWORD=admin
      - ADMIN_NAME=admin
      - ADMIN_EMAIL=admin@example.com
    # highlight-next-line
    volumes:
      # highlight-next-line
      - limesurvey:/var/www/html/upload/surveys
    ports:
      - 8080:8080
    depends_on:
      # highlight-next-line
      limesurvey-db:
        # highlight-next-line
        condition: service_healthy

  limesurvey-db:
    image: docker.io/mysql:8.4
    container_name: limesurvey-db
    # highlight-next-line
    volumes:
      # highlight-next-line
      - data:/var/lib/mysql
    environment:
      - MYSQL_USER=admin
      - MYSQL_PASSWORD=admin
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=limesurvey
    # highlight-next-line
    healthcheck:
      # highlight-next-line
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      # highlight-next-line
      timeout: 10s
      # highlight-next-line
      retries: 10

# highlight-next-line
volumes:
  # highlight-next-line
  limesurvey:
  # highlight-next-line
  data:
```

> **Want to learn more about volumes?:**
>
> In that case, please read this blog post: [Using volumes with Docker, use cases](/blog/docker-volumes)

## Download an old version

> **This section pins MySQL 5.7, which is end-of-life:**
>
> MySQL 5.7 reached end of life in October 2023 and no longer receives security patches. Pinning it is intentional below, because the whole point is to mirror an old production environment on your machine. **Never use `mysql:5.7` for anything other than local reproduction of a legacy setup.**

You know what? It's really easy to download an old version.

Let's imagine the following situation: you need to intervene on an old installation of LimeSurvey. For the example, let's say you need to install a plugin of some kind but, obviously, before doing so on a production site, you're going to get your hands dirty locally. So you need to download the same version as the production version.

Earlier in this article, we saw that we can easily download the 'latest' version.

Let's start again, but this time for a specific version. By looking at the production site, you see f.i. version `3.22.6+200219`.

In our `compose.yaml`, we then need to replace `image: docker.io/martialblog/limesurvey:latest` by something else but what? A valid tag for sure. Go to <https://hub.docker.com/r/martialblog/limesurvey/tags> and, in the `Filter Tags` area, type `3.22.6`, our production version thus. We'll get three images but just one for `apache` (indeed, we wish to use the Docker image having both PHP and Apache). Bingo, now we know our line will be `image: docker.io/martialblog/limesurvey:3.22.6_200219-apache`.

The second part is how to be sure which lines I need to put in the yaml file. For this, just go to <https://github.com/martialblog/docker-limesurvey/releases/tag/> and try to find the same release. Here it's: <https://github.com/martialblog/docker-limesurvey/releases/tag/3.22.6%2B200219>.

Click on the `Source code (zip)` for instance to download the archive and open it. From the archive, retrieve the `compose.yaml` file and pay attention to how the file is configured.

For instance, we can see the version of MySQL used then was `mysql:5.7` (so, use the same to avoid conflicts).

Our `compose.yaml` will then become:

**compose.yaml**

```yaml
name: limesurvey

services:
  limesurvey-app:
    image: docker.io/martialblog/limesurvey:3.22.6_200219-apache
    container_name: limesurvey-app
    restart: always
    environment:
      - DB_TYPE=mysql
      - DB_HOST=limesurvey-db
      - DB_NAME=limesurvey
      - DB_USERNAME=limesurvey
      - DB_PASSWORD=secret
      - ADMIN_USER=admin
      - ADMIN_PASSWORD=admin
      - ADMIN_NAME=admin
      - ADMIN_EMAIL=admin@example.com
    ports:
      - 8080:80
    depends_on:
      limesurvey-db:
        condition: service_healthy

  limesurvey-db:
    image: mysql:5.7
    container_name: limesurvey-db
    environment:
      - MYSQL_USER=limesurvey
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_DATABASE=limesurvey
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      timeout: 10s
      retries: 10
```

Just run `docker compose up --detach` and surf to `http://localhost:`8080 and, congratulations, you have a local LimeSurvey v3.22.6 website.

## Conclusion

Two services in a `compose.yaml`, a `service_healthy` condition so LimeSurvey waits for its database, and a couple of named volumes when you want your surveys to survive: that's all it takes to get a disposable — or a persistent — LimeSurvey on your own machine. And because the version is just a Docker tag, reproducing the exact release running in production is a one-line change.

Same recipe, other tools: browse the [self-hosted](/blog/tags/self-hosted) articles of this blog.
