Missing perl command in Perl image - docker

I'm sure this is an incredibly simple fix. I tried to build Docker image with Perl in it (plus some Perl) modules. However, when I go to run this, it says there is no /bin/perl. The question is:
Why did the Perl Docker Image not have Perl in it?
My Dockerfile below:
FROM perl:5.20
ENV PERL_MM_USE_DEFAULT 1
RUN cpan install Net::SSL inc:latest
RUN mkdir /ssc
COPY /ssc /ssc
RUN mkdir /tmp/ssc-bin-files;cp /ssc/bin/*.sh /tmp/ssc-bin-files;chmod a+rx /tmp/ssc-bin-files/*;cp /tmp/ssc-bin-files/* /ssc/bin
RUN chmod a+rx /ssc/bin/*.sh
ENTRYPOINT ["/ssc/bin/put-and-submit.sh"]
Jenkins Pipeline snippet:
stage('Build, Tag and Push SSC Dockerfile'){
tagAsTest = "${IMAGE_NAME}:test"
REPO = "chq-ic2e-sprint-images-docker-local"
println "Docker App Build"
docker.build(tagAsTest,"-f Dockerfile .")
sh 'docker image ls | grep rules-client'
}
stage('Set image tag to :approved'){
hasReachedDockerComposeUp=false;
REPO = "chq-ic2e-sprint-images-docker-local"
sh "docker tag ${IMAGE_NAME}:test ${IMAGE_NAME}:approved"
buildInfo = rtDocker.push("${IMAGE_NAME}:approved", REPO , buildInfo)
server.publishBuildInfo buildInfo
}
The Jenkins log below:
[Pipeline] sh
+ docker build -t chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/ssc-cost-file-processor:test -f Dockerfile .
Sending build context to Docker daemon 39.42kB
Step 1/8 : FROM perl:5.20
---> bbe5a82c1dbe
Step 2/8 : ENV PERL_MM_USE_DEFAULT 1
---> Using cache
---> ca2769a89ab8
Step 3/8 : RUN cpan install Net::SSL inc:latest
---> Using cache
---> 1e53f0573131
Step 4/8 : RUN mkdir /ssc
---> Using cache
---> a324effec8ce
Step 5/8 : COPY /ssc /ssc
---> d40bf34f8565
Step 6/8 : RUN mkdir /tmp/ssc-bin-files;cp /ssc/bin/*.sh /tmp/ssc-bin-files;chmod a+rx /tmp/ssc-bin-files/*;cp /tmp/ssc-bin-files/* /ssc/bin
---> Running in 02386f41174f
Removing intermediate container 02386f41174f
---> 4767a8e6f23a
Step 7/8 : RUN chmod a+rx /ssc/bin/*.sh
---> Running in 07646aa96048
Removing intermediate container 07646aa96048
---> f070fcd8a9e9
Step 8/8 : ENTRYPOINT ["/ssc/bin/put-and-submit.sh"]
---> Running in e6bab12f8f40
Removing intermediate container e6bab12f8f40
---> 1422df9d957b
Successfully built 1422df9d957b
Successfully tagged chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/ssc-cost-file-processor:test
[Pipeline] sh
+ docker image ls
+ grep rules-client
chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/rules-client approved da334d1d8fae 2 days ago 22.5MB
chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/rules-client test da334d1d8fae 2 days ago 22.5MB
Script is being run via pipeline like this:
stage('Run image'){
sh '''
docker run -i -v \
--mount type=bind,source="$(pwd)/host-dirs,target=/host-dirs" \
chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/ssc-cost-file-processor:approved
sh
'''
}
or from terminal like this:
#!/bin/bash
docker run -it \
--mount type=bind,source="$(pwd)/host-dirs,target=/host-dirs" \
chq-ic2e-sprint-images-docker-local.artifactory.swg-devops.com/ssc-cost-file-processor:approved sh

The perl binary is probably in /usr/local/bin/perl. You can check that in a shell in the running container.
host> docker exec -it your_container bash
container> which perl
/usr/local/bin/perl
container> exit

It sure has perl version 5.20 in it. I'm just curious about the entrypoint script in your dockerfile. You're running a shell script by default when the container is started. What the script starts or runs? If you want to run perl without entering the container, use --entrypoint=perl with your docker run command.
docker run --rm --name perl perl:5.20 perl --version
### Output
This is perl 5, version 20, subversion 3 (v5.20.3) built for x86_64-linux
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2015, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
###

Related

Override UID GID in VSCode Remote-containers session

I am running VSCode in a Windows 10 machine, connecting to a Docker instance on a remote Linux host, to develop C++ projects. The docker instance mounts local folders for source code files, and user is set to match the user on Linux host to avoid file ownership and permission problems.
On Windows 10 I use WSL1, the default user has both UID/GID 1000, and the VSCode's docker processes use these IDs to launch and connect to the docker instance on remote. Is there a way to override the UID/GID VSCode uses so they match the IDs on remote?
Thanks,
Step 1/4 : FROM devenv:latest
---> 120d987bae07
Step 2/4 : RUN groupadd -g 301765 chengd
---> Using cache
---> 58a697ed3565
Step 3/4 : RUN useradd -l -u 301765 -g chengd chengd
---> Using cache
---> b5c7c2b48a83
Step 4/4 : USER chengd
---> Using cache
---> f310c9d1e05b
Successfully built f310c9d1e05b
Successfully tagged vsc-devenv-9da1a5f5cedc16a80d314a148acdbcaf:latest
[7325 ms] Start: Run: wsl -d Ubuntu-20.04 -e /bin/sh -c cd '/home/da/repos/devenv' && DISPLAY='1' ELECTRON_RUN_AS_NODE='1' SSH_ASKPASS='d:\Users\ChengD\.vscode\extensions\ms-vscode-remote.remote-containers-0.177.2\scripts\ssh-askpass.bat' VSCODE_SSH_ASKPASS_NODE='D:\Users\ChengD\AppData\Local\Programs\Microsoft VS Code\Code.exe' VSCODE_SSH_ASKPASS_MAIN='d:\Users\ChengD\.vscode\extensions\ms-vscode-remote.remote-containers-0.177.2\dist\common\sshAskpass.js' VSCODE_SSH_ASKPASS_HANDLE='\\.\pipe\ssh-askpass-7e8e4f69496930d0e88509584ba46ab3357d9ff1-sock' DOCKER_CONTEXT='tcp_201' VSCODE_SSH_ASKPASS_COUNTER='5' docker 'inspect' '--type' 'image' 'vsc-devenv-9da1a5f5cedc16a80d314a148acdbcaf'
[10240 ms] Start: Run: wsl -d Ubuntu-20.04 -e /bin/sh -c cd '/home/da/repos/devenv' && DISPLAY='1' ELECTRON_RUN_AS_NODE='1' SSH_ASKPASS='d:\Users\ChengD\.vscode\extensions\ms-vscode-remote.remote-containers-0.177.2\scripts\ssh-askpass.bat' VSCODE_SSH_ASKPASS_NODE='D:\Users\ChengD\AppData\Local\Programs\Microsoft VS Code\Code.exe' VSCODE_SSH_ASKPASS_MAIN='d:\Users\ChengD\.vscode\extensions\ms-vscode-remote.remote-containers-0.177.2\dist\common\sshAskpass.js' VSCODE_SSH_ASKPASS_HANDLE='\\.\pipe\ssh-askpass-7e8e4f69496930d0e88509584ba46ab3357d9ff1-sock' DOCKER_CONTEXT='tcp_201' VSCODE_SSH_ASKPASS_COUNTER='6' docker 'build' '-f' '/tmp/vsch/updateUID.Dockerfile-0.177.2' '-t' 'vsc-devenv-9da1a5f5cedc16a80d314a148acdbcaf-uid' '--build-arg' 'BASE_IMAGE=vsc-devenv-9da1a5f5cedc16a80d314a148acdbcaf' '--build-arg' 'REMOTE_USER=chengd' '--build-arg' 'NEW_UID=1000' '--build-arg' 'NEW_GID=1000' '--build-arg' 'IMAGE_USER=chengd' '/tmp/vsch'
Solved the problem by setting updateRemoteUserUID to false in devcontainer.json.

Docker build step name cannot start with number

I'm building a docker image for a Sybase database. Docker build command fails because the name of the build step "server" cannot start with a number.
I have searched A LOT for a way to change the build step machine's name and my solution so far is to retry the build until I get a name that starts with a letter...
Step 1/7 : FROM my_image as docker_sybase_db
---> d266899b4eef
Step 2/7 : COPY *.zip /mnt/backup/
---> Using cache
---> 9e8e405848ce
Step 3/7 : COPY entrypoint.sh ~
---> Using cache
---> 5c0c923985db
Step 4/7 : ENV HOSTNAME docker_sybase_db
---> Using cache
---> f2b39a7280a0
Step 5/7 : RUN init_db.sh
---> Running in 0ae1a95b3203
Server name '0ae1a95b3203' begins with an illegal character. The first
character of a server name must be an alphabetic ascii character.
Error running command 'srvbuild -r /tmp/my_super_build.rs':
If I can't modify this old sybase init script, am I out of luck here ?
EDIT: Here is what I am trying to do
Create a database instance
Load a backup
Package that pre-loaded instance into a container.
Loading the backup takes a lot of time and this old database system requires the server name to start with a letter, not a number.
You could try and see if LolHens's idea of changing the hostname in the container namespace (during the docker build) works for you.
docker build . | tee >((grep --line-buffered -Po '(?<=^change-hostname ).*' || true) | \
while IFS= read -r id; do \
nsenter --target "$(docker inspect -f '{{ .State.Pid }}' "$id")"\
--uts hostname 'new-hostname'; \
done)
The docker build output is parsed to:
detect a "change-hostname" directive
do a nsenter, which runs a program in the UTS (UNIX Time Sharing) namespace, with a different hostname (different than the SHA-generated random one)
That means your RUN step should be:
RUN echo "change-hostname $(hostname)"; \
sleep 1; \
printf '%s\n' "$(hostname)" > /etc/hostname; \
printf '%s\t%s\t%s\n' "$(perl -C -0pe 's/([\s\S]*)\t.*$/$1/m' /etc/hosts)" "$(hostname)" > /etc/hosts; \
init_db.sh
That way, init_db.sh should run in an intermediate container with a different hostname (one you do have control over, and which would not start with a number).

Docker Desktop for Windows can't run tagged images

I'm trying to do some basic containers in Windows. I've been using Docker on Linux for years, but this issue is new for me.
Running the command
docker build -f windowsTest3.df -t dockertest . results in a good, tagged build.
...
---> 04064df75127
Step 13/13 : ENTRYPOINT C:/BuildTools/Common7/Tools/VsDevCmd.bat
---> Using cache
---> 9e098cff37a2
Successfully built 9e098cff37a2
Successfully tagged dockertest:latest
However, attempting to run an interactive shell inside the container gives an error. The system cannot find the path specified.
Edit: Can't believe I forgot to list the command...
To start the container interactively, I'm running docker run -it dockertest, but I've also tried docker run -it dockertest cmd and variations of that.
Running docker images shows that the tagged image exists, so I can't figure out what's causing the error.
docker images
C:\Users\devuser.DESKTOP-UV8CO47\Desktop\tmp>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockertest latest 9e098cff37a2 41 minutes ago 12.3GB
Here are my path locations:
C:\ProgramData\DockerDesktop\version-bin;C:\Program Files\Docker\Docker\Resources\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Python37-32\Scripts\;C:\Program Files (x86)\Python37-32\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Git\cmd;C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin;C:\Program Files\Amazon\AWSCLI\bin\;C:\Program Files (x86)\GnuWin32\bin;C:\Program Files\CMake\bin;C:\Program Files\dotnet\;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\ProgramData\chocolatey\bin;C:\PRQA\PRQA-Framework-2.4.0\common\bin;C:\Users\DevUser\AppData\Local\Microsoft\WindowsApps;C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin;C:\Program Files\Git\bin;C:\Program Files\7-Zip;C:\Program Files\nssm-2.24\win64
Here is a slightly abridged version of the dockerfile
FROM mcr.microsoft.com/windows:10.0.17763.316-amd64
# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]
# Download the Build Tools bootstrapper.
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:/tmp/vs_buildtools.exe
# Install Build Tools excluding workloads and components with known issues.
RUN C:/tmp/vs_buildtools.exe --quiet --wait --norestart --nocache \
--installPath C:\BuildTools \
--all \
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 \
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 \
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 \
--remove Microsoft.VisualStudio.Component.Windows81SDK \
|| IF "%ERRORLEVEL%"=="3010" EXIT 0
ENV chocolateyUseWindowsCompression=false
RUN powershell set-executionpolicy remotesigned
RUN powershell -Command Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
RUN powershell -Command Install-PackageProvider -Name chocolatey -Force
RUN powershell -command "choco install -y git"
ENTRYPOINT C:/BuildTools/Common7/Tools/VsDevCmd.bat
Please check if VsDevCmd.bat is available inside the container when it's starting, at C:/BuildTools/Common7/Tools/ path
Also as per this Doc reference
On Windows, file paths specified in the CMD instruction must use
forward slashes or have escaped backslashes \.
CMD c:\Apache24\bin\httpd.exe -w
Maybe try your ENTRYPOINT like this.
ENTRYPOINT C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat
You can also use CMD
CMD C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat
Can also try this as well but recommended is above one
ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat

Dockerfile RUN lpadmin to add a printer not working in the built image?

I want to add a printer in Dockerfile RUN command, so this is my Dockerfile
FROM dassh/eline:base
MAINTAINER dassh
# start cups service is necessary to run lpadmin command
RUN service cups start && lpadmin -p VLM2601 -v EleanBackend:/tmp -m
VLM2601_gdi.ppd -E && echo done
Build procedure
docker build -t dassh/eline .
Sending build context to Docker daemon 722.9kB
Step 1/3 : FROM dassh/eline:base
---> 712dce8cd557
Step 2/3 : MAINTAINER dassh
---> Running in 2f3f5f80b665
Removing intermediate container 2f3f5f80b665
---> 2b53b81d6ff4
Step 3/3 : RUN service cups start && lpadmin -p VLM2601 -v EleanBackend:/tmp -m VLM2601_gdi.ppd -E && echo done
---> Running in f176fbdf765e
* Starting Common Unix Printing System cupsd
...done.
done
Removing intermediate container f176fbdf765e
---> e229e278b085
Successfully built e229e278b085
Successfully tagged dassh/eline:latest
The build was successful without any error. But when I started a container with this image, I found that the printer wasn't added.
dassh#ubuntu:~$ docker run -itd dassh/eline /bin/bash
a8785057e71a598cd391f355848819295fef8e311090f70cbae95ca5360856c2
dassh#ubuntu:~$ docker cp ~/123.pdf a8:/
dassh#ubuntu:~$ docker attach a8
root#a8785057e71a:/pdf_to_prn#
root#a8785057e71a:/pdf_to_prn# service cups start
* Starting Common Unix Printing System cupsd [ OK ]
root#a8785057e71a:/pdf_to_prn# lp -o fit-to-page -o media=A4 -d VLM2601 /123.pdf
lp: The printer or class does not exist.
The command returns an error that the printer does not exist, but when I execute add printer command in the container manually, and run lp command again, everything is fine.
root#a8785057e71a:/pdf_to_prn# lpadmin -p VLM2601 -v EleanBackend:/tmp -m VLM2601_gdi.ppd -E
root#a8785057e71a:/pdf_to_prn# lp -o fit-to-page -o media=A4 -d VLM2601 /123.pdf
request id is VLM2601-1 (1 file(s))
Therefore, my adding printer command has no issues. So what is happening?
The problem cause by use lpadmin create printer.
system get printers by file /etc/cups/printers.conf.
use lpadmin add a printer will generate or update file /etc/cups/printers.conf.
step 2 is asynchronous! (It takes almost 30s in my test after execute lpadmin command)
Dockerfile RUN this step complete before file /etc/cups/printers.conf generated.

How to get /etc/profile to run automatically in Alpine / Docker

How can I get /etc/profile to run automatically when starting an Alpine Docker container interactively? I have added some aliases to an aliases.sh file and placed it in /etc/profile.d, but when I start the container using docker run -it [my_container] sh, my aliases aren't active. I have to manually type . /etc/profile from the command line each time.
Is there some other configuration necessary to get /etc/profile to run at login? I've also had problems with using a ~/.profile file. Any insight is appreciated!
EDIT:
Based on VonC's answer, I pulled and ran his example ruby container. Here is what I got:
$ docker run --rm --name ruby -it codeclimate/alpine-ruby:b42
/ # more /etc/profile.d/rubygems.sh
export PATH=$PATH:/usr/lib/ruby/gems/2.0.0/bin
/ # env
no_proxy=*.local, 169.254/16
HOSTNAME=6c7e93ebc5a1
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
/ # exit
Although the /etc/profile.d/rubygems.sh file exists, it is not being run when I login and my PATH environment variable is not being updated. Am I using the wrong docker run command? Is something else missing? Has anyone gotten ~/.profile or /etc/profile.d/ files to work with Alpine on Docker? Thanks!
The default shell in Alpine Linux is ash.
Ash will only read the /etc/profile and ~/.profile files if it is started as a login shell sh -l.
To force Ash to source the /etc/profile or any other script you want upon its invocation as a non login shell, you need to setup an environment variable called ENV before launching Ash.
e.g. in your Dockerfile
FROM alpine:3.5
ENV ENV="/root/.ashrc"
RUN echo "echo 'Hello, world!'" > "$ENV"
When you build that you get:
deployer#ubuntu-1604-amd64:~/blah$ docker build --tag test .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM alpine:3.5
3.5: Pulling from library/alpine
627beaf3eaaf: Pull complete
Digest: sha256:58e1a1bb75db1b5a24a462dd5e2915277ea06438c3f105138f97eb53149673c4
Status: Downloaded newer image for alpine:3.5
---> 4a415e366388
Step 2/3 : ENV ENV "/root/.ashrc"
---> Running in a9b6ff7303c2
---> 8d4af0b7839d
Removing intermediate container a9b6ff7303c2
Step 3/3 : RUN echo "echo 'Hello, world!'" > "$ENV"
---> Running in 57c2fd3353f3
---> 2cee6e034546
Removing intermediate container 57c2fd3353f3
Successfully built 2cee6e034546
Finally, when you run the newly generated container, you get:
deployer#ubuntu-1604-amd64:~/blah$ docker run -ti test /bin/sh
Hello, world!
/ # exit
Notice the Ash shell didn't run as a login shell.
So to answer your query, replace
ENV ENV="/root/.ashrc"
with:
ENV ENV="/etc/profile"
and Alpine Linux's Ash shell will automatically source the /etc/profile script each time the shell is launched.
Gotcha: /etc/profile is normally meant to only be sourced once! So, I would advise that you don't source it and instead source a /root/.somercfile instead.
Source: https://stackoverflow.com/a/40538356
You still can try in your Dockerfile a:
RUN echo '\
. /etc/profile ; \
' >> /root/.profile
(assuming the current user is root. If not, replace /root with the full home path)
That being said, those /etc/profile.d/xx.sh should run.
See codeclimate/docker-alpine-ruby as an example:
COPY files /
With 'files/etc" including an files/etc/profile.d/rubygems.sh running just fine.
In the OP project Dockerfile, there is a
COPY aliases.sh /etc/profile.d/
But the default shell is not a login shell (sh -l), which means profile files (or those in /etc/profile.d) are not sourced.
Adding sh -l would work:
docker#default:~$ docker run --rm --name ruby -it codeclimate/alpine-ruby:b42 sh -l
87a58e26b744:/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/ruby/gems/2.0.0/bin
As mentioned by Jinesh before, the default shell in Alpine Linux is ash
localhost:~$ echo $SHELL
/bin/ash
localhost:~$
Therefore simple solution is too add your aliases in .profile. In this case, I put all my aliases in ~/.ash_aliases
localhost:~$ cat .profile
# ~/.profile
# Alias
if [ -f ~/.ash_aliases ]; then
. ~/.ash_aliases
fi
localhost:~$
.ash_aliases file
localhost:~$ cat .ash_aliases
alias a=alias
alias c=clear
alias f=file
alias g=grep
alias l='ls -lh'
localhost:~$
And it works :)
I use this:
docker exec -it my_container /bin/ash '-l'
The -l flag passed to ash will make it behave as a login shell, thus reading ~/.profile

Resources