1

I have an example script called main.cpp which reads as follows:

#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main() {
    std::string line;
    boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );

    while (std::cin) {
        std::getline(std::cin, line);
        boost::smatch matches;
        if (boost::regex_match(line, matches, pat))
            std::cout << matches[2] << std::endl;
    }
}

The output should be

Foo
Bar: 4
Bar: 4

It is compiled with g++ -o myprogram main.cpp -lboost_signals

With a dockerfile containing:

# Use an official Ubuntu image as the base image
FROM ubuntu:20.04
# Set the working directory inside the container
WORKDIR /app
# Update apt repository and install build tools and Boost library
RUN apt-get update && apt-get install -y \
    build-essential \
    libboost-all-dev \
    && rm -rf /var/lib/apt/lists/*
# Copy the C++ source code into the container
COPY main.cpp /app/main.cpp
# Compile the program using g++
RUN g++ -o myprogram main.cpp -lboost_signals
# Set the default command to run the compiled program
CMD ["./main"]

The thing is, I'm not convinced this dockerfile is 1) optimal 2) reliable for my needs. How can I improve my dockerfile to further streamline my work? TIA

Further, when running the container, it fails:

docker build -t cpp-boost-example .
[+] Building 33.7s (11/11) FINISHED                                                                                                                                                                                                                                                                                                                                   docker:desktop-linux
 => [internal] load build definition from dockerfile                                                                                                                                                                                                                                                                                                                                  0.0s
 => => transferring dockerfile: 1.16kB                                                                                                                                                                                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/ubuntu:20.04                                                                                                                                                                                                                                                                                                                       0.4s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                                                                                                                       0.0s
 => CACHED [1/7] FROM docker.io/library/ubuntu:20.04@sha256:8e5c4f0285ecbb4ead070431d29b576a530d3166df73ec44affc1cd27555141b                                                                                                                                                                                                                                                          0.0s
 => => resolve docker.io/library/ubuntu:20.04@sha256:8e5c4f0285ecbb4ead070431d29b576a530d3166df73ec44affc1cd27555141b                                                                                                                                                                                                                                                                 0.0s
 => [internal] load build context                                                                                                                                                                                                                                                                                                                                                     0.0s
 => => transferring context: 114B                                                                                                                                                                                                                                                                                                                                                     0.0s
 => [2/7] RUN ln -snf /usr/share/zoneinfo/$CONTAINER_TIMEZONE /etc/localtime && echo $CONTAINER_TIMEZONE > /etc/timezone                                                                                                                                                                                                                                                              0.1s
 => [3/7] RUN apt-get update && apt-get install -y tzdata                                                                                                                                                                                                                                                                                                                             2.7s
 => [4/7] WORKDIR /app                                                                                                                                                                                                                                                                                                                                                                0.0s
 => [5/7] RUN apt-get update && apt-get install -y     build-essential     libboost-all-dev     && rm -rf /var/lib/apt/lists/*                                                                                                                                                                                                                                                       29.8s
 => [6/7] COPY main.cpp /app/main.cpp                                                                                                                                                                                                                                                                                                                                                 0.1s 
 => ERROR [7/7] RUN g++ -o myprogram main.cpp -lboost_signals                                                                                                                                                                                                                                                                                                                         0.5s 
------                                                                                                                                                                                                                                                                                                                                                                                     
 > [7/7] RUN g++ -o myprogram main.cpp -lboost_signals:                                                                                                                                                                                                                                                                                                                                    
0.439 /usr/bin/ld: cannot find -lboost_signals                                                                                                                                                                                                                                                                                                                                             
0.439 collect2: error: ld returned 1 exit status                                                                                                                                                                                                                                                                                                                                           
------
dockerfile:23
--------------------
  21 |     COPY main.cpp /app/main.cpp
  22 |     # Compile the program using g++
  23 | >>> RUN g++ -o myprogram main.cpp -lboost_signals
  24 |     # Set the default command to run the compiled program
  25 |     CMD ["./main"]
--------------------
ERROR: failed to solve: process "/bin/sh -c g++ -o myprogram main.cpp -lboost_signals" did not complete successfully: exit code: 1
9
  • "optimal" and "reliable" by what metric? Size? Ability to rebuild in the future? Portability to other base container images? As a start, you probably want to avoid shipping a container image with all of the build tools and dependencies; look into multi-stage builds so you only keep the main binary and any runtime dependencies like boost. Commented Jan 13 at 12:17
  • Well yes I’m very inexperienced when it comes to Docker so I’m not sure how exactly to do that. Is there a guide? Commented Jan 13 at 12:24
  • 1
    Multi-stage builds are a part of every "docker best practices" guide i've read. I'll just leave you with the official Docker documentation Commented Jan 13 at 12:26
  • looks like libboost-all-dev doesn't include boost_signals launchpad.net/ubuntu/focal/amd64/libboost-all-dev/…, signals doesn't exist in modern versions of boost bugs.launchpad.net/ubuntu/+source/boost-defaults/+bug/1876788, you're not using it so why link to it? Commented Jan 13 at 12:39
  • Use std <regex> library instead of boost. If you need boost for anything more, learn to link it as static library or identify, locate and copy the required dll files; On a typical POSIX system, ldd command could work. Commented Jan 13 at 15:08

1 Answer 1

2

On the specific build error, the current Boost documentation states:

Linking against the Signals2 library

Unlike the original Boost.Signals library, Boost.Signals2 is currently header-only.

You can search on https://packages.debian.org/ for libboost_signals.so, which is the specific file that -lboost_signals would look for, and it just doesn't exist in Debian stable. So you need to

  1. Update to Boost.Signals2 if you haven't already; and
  2. Remove that -l option.

For compiled languages (like C++) you typically want to use a Docker multi-stage build for your image. The idea is that you can have a first build stage with all of the required tools to build the application, and a second build stage that only contain what's needed to run it. In particular you don't need the C++ compiler in the final image, and build-essential brings along a huge amount of tools and header files.

I'd also typically recommend putting your compiled application in a normal binary directory, like /usr/local/bin, which slightly simplifies running it.

# This is basically what you had originally:
FROM ubuntu:20.04 AS build  # <-- added build-stage name
WORKDIR /app
RUN apt-get update && apt-get install -y \
    build-essential \
    libboost-all-dev \
    && rm -rf /var/lib/apt/lists/*
COPY main.cpp ./
RUN g++ -o myprogram main.cpp  # <-- remove -lboost_signals here
# End of first stage.

# The second stage actually runs the application.
FROM ubuntu:20.04

# If your application does need any C shared libraries to run,
# install these here (*not* -dev versions)
# RUN apt-get update && apt-get install -y libboost-...

# Copy the compiled application binary into the final image
COPY --from=build /app/myprogram /usr/local/bin

# Set the standard image metadata to run it
CMD ["myprogram"]
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer. Unfortunately, when I run this I get
``` docker build -t boosttest . -------------------- 1 | # This is basically what you had originally: 2 | # This is basically what you had originally: 3 | >>> FROM ubuntu:20.04 AS build # <-- added build-stage name 4 | WORKDIR /app 5 | RUN apt-get update && apt-get install -y \ -------------------- ERROR: failed to solve: dockerfile parse error on line 3: FROM requires either one or three arguments ```
That looks like a terrible bug in the Docker parser. Remove the comment from the FROM line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.