[Dockerfile] Cleanest way to install localstack in a Docker image

Hello,

I would like to create a Docker image for my Gitlab runner, and execute pipelines for NodeJS applications, but I wasn’t satisfied with the documentation.

I have created “Version A” and “Version B” of my Dockerfile, maybe a solution already exist and I’m just re-inventing the wheel? I don’t know

Version A

My first solution was:

FROM localstack/localstack:1.0.3

RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# Show installed versions
RUN node --version
RUN npm --version
RUN localstack --version

=> But the last line generates /bin/bash: localstack: command not found, even if the file exist! drwxr-xr-x 1 root root 4096 Jul 30 00:39 localstack

Version B

FROM node:16

RUN apt-get update
RUN apt-get install -y python3 python3-pip
RUN apt-get update

# RUN add-apt-repository universe # Does not work on Debian based images
RUN pip3 install --upgrade pip
RUN pip3 install localstack

# Show installed versions
RUN node --version
RUN npm --version
RUN python3 --version
RUN pip3 --version
RUN localstack --version

=> That “Version B” requires ton of additional installation like python3, pip3, etc… There’s only an additional Docker installation missing to make it work, so I think I will be able to reach my goal but I just don’t like “Version B”, it’s too ugly

Could you give me some advice/solution so I can properly and easily install a fully operational localstack in my Docker image?

Note: Some people may suggest a docker-compose.yml oriented solution but I just don’t want to maintain this file 50 times in 50 projects

Thanks

Hi @gokan , thanks for reporting. We’d definitely recommend using Version A, :+1: as the LocalStack Docker image contains several customizations and optimizations that would be hard to replicate over time.

Please note that by default LocalStack is installed in a Python virtual environment inside the /opt/code/localstack/.venv folder in the image. You should be able to get it working by activating the virtualenv first, then running the localstack command:

RUN . .venv/bin/activate; localstack --version

… or alternatively:

RUN .venv/bin/localstack --version

Hope that helps, please keep us posted on how it goes…!

Hello @whummer , thanks for your answer.

The built of the image worked:

FROM localstack/localstack:1.0.3

RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# Show installed versions
RUN node --version
RUN npm --version
RUN .venv/bin/localstack --version

And localstack is accessible from /opt/code/localstack/.venv/bin/localstack in my Gitlab runner, BUT docker is not available:

localstack.utils.container_utils.container_client.ContainerException: Docker not available

Detailed stacktrace:

$ LOCALSTACK="/opt/code/localstack/.venv/bin/localstack"
$ $LOCALSTACK start -d && sleep 10s && $LOCALSTACK status services
     __                     _______ __             __
    / /   ____  _________ _/ / ___// /_____ ______/ /__
   / /   / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
  / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
 /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
 💻 LocalStack CLI 1.0.3
[07:40:33] starting LocalStack in Docker mode 🐳               localstack.py:140
           preparing environment                                bootstrap.py:667
Traceback (most recent call last):
  File "/opt/code/localstack/.venv/bin/localstack", line 7, in <module>
    exec(compile(f.read(), __file__, 'exec'))
  File "/opt/code/localstack/bin/localstack", line 23, in <module>
    main()
  File "/opt/code/localstack/bin/localstack", line 19, in main
    main.main()
  File "/opt/code/localstack/localstack/cli/main.py", line 6, in main
    cli()
  File "/opt/code/localstack/localstack/cli/plugin.py", line 15, in __call__
    self.group(*args, **kwargs)
  File "/opt/code/localstack/.venv/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/opt/code/localstack/.venv/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/opt/code/localstack/.venv/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/code/localstack/.venv/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/code/localstack/.venv/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/opt/code/localstack/localstack/utils/analytics/cli.py", line 66, in publisher_wrapper
    return fn(*args, **kwargs)
  File "/opt/code/localstack/localstack/cli/localstack.py", line 151, in cmd_start
    bootstrap.start_infra_in_docker_detached(console)
  File "/opt/code/localstack/localstack/utils/bootstrap.py", line 669, in start_infra_in_docker_detached
    prepare_docker_start()
  File "/opt/code/localstack/localstack/utils/bootstrap.py", line 519, in prepare_docker_start
    if DOCKER_CLIENT.is_container_running(container_name):
  File "/opt/code/localstack/localstack/utils/container_utils/container_client.py", line 469, in is_container_running
    return container_name in self.get_running_container_names()
  File "/opt/code/localstack/localstack/utils/container_utils/container_client.py", line 463, in get_running_container_names
    result = self.list_containers(all=False)
  File "/opt/code/localstack/localstack/utils/container_utils/docker_sdk_client.py", line 166, in list_containers
    container_list = self.client().containers.list(filters=filter, all=all)
  File "/opt/code/localstack/localstack/utils/container_utils/docker_sdk_client.py", line 51, in client
    raise ContainerException("Docker not available")
localstack.utils.container_utils.container_client.ContainerException: Docker not available

I have checked the source code and I guess the Optional is empty. Also, if I do docker info on the Docker container (run by Gitlab runner) then I get: /scripts-19210-2786106/step_script: line 166: docker: command not found