some error with the 'ln' scripts - linux

anybody is familiar with the etcd project? Or we'd better forget the project when talk about this issue. The issue is
$ build
ln: `gopath/src/github.com/coreos/etcd': cannot overwrite directory
when exec the build shell
and the content is:
#!/bin/sh -e
if [ ! -h gopath/src/github.com/coreos/etcd ]; then
mkdir -p gopath/src/github.com/coreos/
ln -s ../../../.. gopath/src/github.com/coreos/etcd
fi
export GOBIN=${PWD}/bin
export GOPATH=${PWD}/gopath
export GOFMTPATH="./bench ./config ./discovery ./etcd ./error ./http ./log main.go ./metrics ./mod ./server ./store ./tests"
# Don't surprise user by formatting their codes by stealth
if [ "--fmt" = "$1" ]; then
gofmt -s -w -l $GOFMTPATH
fi
go install github.com/coreos/etcd
go install github.com/coreos/etcd/bench
Some addition:
My system is windows 7
I run the shell on git bash.
issue reproduce:
step1: open the git bash
step2: git clone git#github.com:coreos/etcd.git
step3: cd etcd
step4: build

As mentioned in "Git Bash Shell fails to create symbolic links" (since you are using the script in a git bash on Windows 7)
the ln that shipped with msysGit simply tries to copy its arguments, rather than fiddle with links. This is because links only work (sort of) on NTFS filesystems, and the MSYS team didn't want to reimplement ln.
A workaround is to run mklink from Bash.
This also allows you to create either a Symlink or a Junction.
So 'ln' wouldn't work as expected by default, in the old shell that ships with Git for Windows.

Here's solution. Tbh it is a workaround, but since you're on Windows, I don't see another way.
Start a command line, and enter there to the directory with the script. There should be a path gopath/src/github.com/coreos/ (if no such a path, you must create it). Next issue a command
mklink /D "gopath/src/github.com/coreos/etcd" "../../../../"
Next you should edit the build script to delete a lines with creation symlink and a directory. E.g.
#!/bin/sh -e
export GOBIN=${PWD}/bin
export GOPATH=${PWD}/gopath
export GOFMTPATH="./bench ./config ./discovery ./etcd ./error ./http ./log main.go ./metrics ./mod ./server ./store ./tests"
# Don't surprise user by formatting their codes by stealth
if [ "--fmt" = "$1" ]; then
gofmt -s -w -l $GOFMTPATH
fi
go install github.com/coreos/etcd
go install github.com/coreos/etcd/bench
Note, that I am just removed 4 lines of code. Next you run the script, and this should work.

You shouldn't be using git clone and the build sh script. Use the go get command. For example, on Windows 7,
Microsoft Windows [Version 6.1.7601]
C:\>set gopath
GOPATH=C:\gopath
C:\>go version
go version go1.3 windows/amd64
C:\>go get -v -u github.com/coreos/etcd
github.com/coreos/etcd (download)
github.com/coreos/etcd/third_party/bitbucket.org/kardianos/osext
github.com/coreos/etcd/pkg/strings
github.com/coreos/etcd/error
github.com/coreos/etcd/third_party/github.com/coreos/go-etcd/etcd
github.com/coreos/etcd/http
github.com/coreos/etcd/third_party/github.com/coreos/go-log/log
github.com/coreos/etcd/third_party/github.com/rcrowley/go-metrics
github.com/coreos/etcd/mod/dashboard/resources
github.com/coreos/etcd/log
github.com/coreos/etcd/third_party/github.com/gorilla/context
github.com/coreos/etcd/third_party/github.com/gorilla/mux
github.com/coreos/etcd/mod/dashboard
github.com/coreos/etcd/discovery
github.com/coreos/etcd/pkg/btrfs
github.com/coreos/etcd/pkg/http
github.com/coreos/etcd/third_party/code.google.com/p/gogoprotobuf/proto
github.com/coreos/etcd/mod/leader/v2
github.com/coreos/etcd/mod/lock/v2
github.com/coreos/etcd/metrics
github.com/coreos/etcd/third_party/github.com/mreiferson/go-httpclient
github.com/coreos/etcd/mod
github.com/coreos/etcd/third_party/github.com/BurntSushi/toml
github.com/coreos/etcd/third_party/github.com/goraft/raft/protobuf
github.com/coreos/etcd/third_party/github.com/goraft/raft
github.com/coreos/etcd/store
github.com/coreos/etcd/server/v1
github.com/coreos/etcd/server/v2
github.com/coreos/etcd/store/v2
github.com/coreos/etcd/server
github.com/coreos/etcd/config
github.com/coreos/etcd/etcd
github.com/coreos/etcd
C:\>

Related

Change directory in a startup script debian

I am running a debian VM Instance using GCP Compute Engine and I have added a automation script to be executed on startup.
There are few tools which will be downloaded on startup. Only issue is, everything is getting downloaded in / directory.
I need to download everything in $HOME directory.
Different ways I have tried
#!/bin/bash
set -x
cd $HOME
mkdir $HOME/test
cd $HOME/test
apt install wget -y
wget https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz
#!/bin/bash
set -x
source $HOME
mkdir $HOME/something
#!/bin/bash
set -x
cd $HOME
mkdir $HOME/something
exec bash
Still it is downloaded in / directory. What else can be done here?
You are trying to make 2 things : install wget package and download another one.
Why don't you tried to install wget manually ?
apt-get install wget
You have then to store the full path for your script, and download the package needed it it. Try this :
#!/bin/bash
homePath=$HOME
mkdir $HOME/test
wget https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz -P $homePath/test/

Not working „source ~/.profile“ inside bash script

To permanently update ~/.profile with source, only working on manual input. Also reboot of the whole system won‘t update ~/.profile and i need to update it manual.
Is there a special code style to use it as working code inside a bash/shell script or is this special code not intended to be used in automated scripts?
Need it to automate installation of golang.
In the following code the line "source ~/.profile" won't work, and without any error messages, the rest is working fine:
#!/bin/bash
sudo apt update
sudo apt -y upgrade
cd ~
curl -O https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
tar xvf go1.12.5.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
cd ~
sudo rm go1.12.5.linux-amd64.tar.gz
sudo echo "export GOPATH=\$HOME/work" >> ~/.profile
sudo echo "export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
source ~/.profile
Preferred:
Source the script itself rather than running it - then the commands in the script are run in the current shell, including the source ~/.profile.
Alternative (since this replaces the running shell, history, variable values, and other state will be lost. So there should be a very good reason to use this method):
Use exec bash or something similar instead of source ~/.profile - this replaces the currently running Bash with another instance which will itself load the new .profile.
Here is a refactoring which defers the decision to the user and cleans up the script somewhat.
#!/bin/bash
# Put this in a variable so there is only one place to update
tarball='go1.12.5.linux-amd64.tar.gz'
sudo apt update
sudo apt -y upgrade
# cd || why would you?
curl -O "https://dl.google.com/go/$tarball"
tar xvf "$tarball"
sudo chown -R root:root ./go
sudo mv go /usr/local
rm "$tarball"
printf '%s\n' "export GOPATH=\$HOME/work" \
"export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
echo "$0: done. source ~/.profile or exec bash to activate new settings." >&2

Sourcing ("dotting") shell script from Docker [duplicate]

I have a Dockerfile that I am putting together to install a vanilla python environment (into which I will be installing an app, but at a later date).
FROM ubuntu:12.04
# required to build certain python libraries
RUN apt-get install python-dev -y
# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip
# install and configure virtualenv
RUN pip install virtualenv
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh
The build runs ok until the last line, where I get the following exception:
[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
---> Running in 8b0145d2c80d
---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
---> Running in 9d2552712ddf
---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
---> Running in c13a187261ec
/bin/sh: 1: source: not found
If I ls into that directory (just to test that the previous steps were committed) I can see that the files exist as expected:
$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh
If I try just running the source command I get the same 'not found' error as above. If I RUN an interactive shell session however, source does work:
$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]
I can run the script from here, and then happily access workon, mkvirtualenv etc.
I've done some digging, and initially it looked as if the problem might lie in the difference between bash as the Ubuntu login shell, and dash as the Ubuntu system shell, dash not supporting the source command.
However, the answer to this appears to be to use '.' instead of source, but this just causes the Docker runtime to blow up with a go panic exception.
What is the best way to run a shell script from a Dockerfile RUN instruction to get around this (am running off the default base image for Ubuntu 12.04 LTS).
Original Answer
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
This should work for every Ubuntu docker base image. I generally add this line for every Dockerfile I write.
Edit by a concerned bystander
If you want to get the effect of "use bash instead of sh throughout this entire Dockerfile", without altering and possibly damaging* the OS inside the container, you can just tell Docker your intention. That is done like so:
SHELL ["/bin/bash", "-c"]
* The possible damage is that many scripts in Linux (on a fresh Ubuntu install grep -rHInE '/bin/sh' / returns over 2700 results) expect a fully POSIX shell at /bin/sh. The bash shell isn't just POSIX plus extra builtins. There are builtins (and more) that behave entirely different than those in POSIX. I FULLY support avoiding POSIX (and the fallacy that any script that you didn't test on another shell is going to work because you think you avoided basmisms) and just using bashism. But you do that with a proper shebang in your script. Not by pulling the POSIX shell out from under the entire OS. (Unless you have time to verify all 2700 plus scripts that come with Linux plus all those in any packages you install.)
More detail in this answer below. https://stackoverflow.com/a/45087082/117471
The default shell for the RUN instruction is ["/bin/sh", "-c"].
RUN "source file" # translates to: RUN /bin/sh -c "source file"
Using SHELL instruction, you can change default shell for subsequent RUN instructions in Dockerfile:
SHELL ["/bin/bash", "-c"]
Now, default shell has changed and you don't need to explicitly define it in every RUN instruction
RUN "source file" # now translates to: RUN /bin/bash -c "source file"
Additional Note: You could also add --login option which would start a login shell. This means ~/.bashrc for example would be read and you don't need to source it explicitly before your command
Simplest way is to use the dot operator in place of source, which is the sh equivalent of the bash source command:
Instead of:
RUN source /usr/local/bin/virtualenvwrapper.sh
Use:
RUN . /usr/local/bin/virtualenvwrapper.sh
If you are using Docker 1.12 or newer, just use SHELL !
Short Answer:
general:
SHELL ["/bin/bash", "-c"]
for python vituralenv:
SHELL ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]
Long Answer:
from https://docs.docker.com/engine/reference/builder/#shell
SHELL ["executable", "parameters"]
The SHELL instruction allows the default shell used for the shell form
of commands to be overridden. The default shell on Linux is
["/bin/sh", "-c"], and on Windows is ["cmd", "/S", "/C"]. The SHELL
instruction must be written in JSON form in a Dockerfile.
The SHELL instruction is particularly useful on Windows where there
are two commonly used and quite different native shells: cmd and
powershell, as well as alternate shells available including sh.
The SHELL instruction can appear multiple times. Each SHELL
instruction overrides all previous SHELL instructions, and affects all
subsequent instructions. For example:
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
The following instructions can be affected by the SHELL instruction
when the shell form of them is used in a Dockerfile: RUN, CMD and
ENTRYPOINT.
The following example is a common pattern found on Windows which can
be streamlined by using the SHELL instruction:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
The command invoked by docker will be:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
This is inefficient for two reasons. First, there is an un-necessary
cmd.exe command processor (aka shell) being invoked. Second, each RUN
instruction in the shell form requires an extra powershell -command
prefixing the command.
To make this more efficient, one of two mechanisms can be employed.
One is to use the JSON form of the RUN command such as:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
While the JSON form is unambiguous and does not use the un-necessary
cmd.exe, it does require more verbosity through double-quoting and
escaping. The alternate mechanism is to use the SHELL instruction and
the shell form, making a more natural syntax for Windows users,
especially when combined with the escape parser directive:
# escape=`
FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
Resulting in:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
---> Running in 6fcdb6855ae2
---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
---> Running in d0eef8386e97
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/28/2016 11:26 AM Example
---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
---> Running in be6d8e63fe75
hello world
---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>
The SHELL instruction could also be used to modify the way in which a
shell operates. For example, using SHELL cmd /S /C /V:ON|OFF on
Windows, delayed environment variable expansion semantics could be
modified.
The SHELL instruction can also be used on Linux should an alternate
shell be required such as zsh, csh, tcsh and others.
The SHELL feature was added in Docker 1.12.
I had the same problem and in order to execute pip install inside virtualenv I had to use this command:
RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
&& mkvirtualenv myapp \
&& workon myapp \
&& pip install -r /mycode/myapp/requirements.txt"
I hope it helps.
Building on the answers on this page I would add that you have to be aware that each RUN statement runs independently of the others with /bin/sh -c and therefore won't get any environment vars that would normally be sourced in login shells.
The best way I have found so far is to add the script to /etc/bash.bashrc and then invoke each command as bash login.
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "your command"
You could for instance install and setup virtualenvwrapper, create the virtual env, have it activate when you use a bash login, and then install your python modules into this env:
RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "mkvirtualenv myapp"
RUN echo "workon mpyapp" >> /etc/bash.bashrc
RUN /bin/bash --login -c "pip install ..."
Reading the manual on bash startup files helps understand what is sourced when.
According to https://docs.docker.com/engine/reference/builder/#run the default [Linux] shell for RUN is /bin/sh -c. You appear to be expecting bashisms, so you should use the "exec form" of RUN to specify your shell.
RUN ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]
Otherwise, using the "shell form" of RUN and specifying a different shell results in nested shells.
# don't do this...
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"
# because it is the same as this...
RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
If you have more than 1 command that needs a different shell, you should read https://docs.docker.com/engine/reference/builder/#shell and change your default shell by placing this before your RUN commands:
SHELL ["/bin/bash", "-c"]
Finally, if you have placed anything in the root user's .bashrc file that you need, you can add the -l flag to the SHELL or RUN command to make it a login shell and ensure that it gets sourced.
Note: I have intentionally ignored the fact that it is pointless to source a script as the only command in a RUN.
According to Docker documentation
To use a different shell, other than ‘/bin/sh’, use the exec form passing in the desired shell. For example,
RUN ["/bin/bash", "-c", "echo hello"]
See https://docs.docker.com/engine/reference/builder/#run
I also had issues in running source in a Dockerfile
This runs perfectly fine for building CentOS 6.6 Docker container, but gave issues in Debian containers
RUN cd ansible && source ./hacking/env-setup
This is how I tackled it, may not be an elegant way but this is what worked for me
RUN echo "source /ansible/hacking/env-setup" >> /tmp/setup
RUN /bin/bash -C "/tmp/setup"
RUN rm -f /tmp/setup
If you have SHELL available you should go with this answer -- don't use the accepted one, which forces you to put the rest of the dockerfile in one command per this comment.
If you are using an old Docker version and don't have access to SHELL, this will work so long as you don't need anything from .bashrc (which is a rare case in Dockerfiles):
ENTRYPOINT ["bash", "--rcfile", "/usr/local/bin/virtualenvwrapper.sh", "-ci"]
Note the -i is needed to make bash read the rcfile at all.
You might want to run bash -v to see what's being sourced.
I would do the following instead of playing with symlinks:
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
This is my solution on "Ubuntu 20.04"
RUN apt -y update
RUN apt -y install curl
SHELL ["/bin/bash", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN source /root/.bashrc
RUN bash -c ". /root/.nvm/nvm.sh && nvm install v16 && nvm alias default v16 && nvm use default"
This might be happening because source is a built-in to bash rather than a binary somewhere on the filesystem. Is your intention for the script you're sourcing to alter the container afterward?
I ended up putting my env stuff in .profile and mutated SHELL something like
SHELL ["/bin/bash", "-c", "-l"]
# Install ruby version specified in .ruby-version
RUN rvm install $(<.ruby-version)
# Install deps
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install
CMD rvm use $(<.ruby-version) && ./myscript.rb
If you're just trying to use pip to install something into the virtualenv, you can modify the PATH env to look in the virtualenv's bin folder first
ENV PATH="/path/to/venv/bin:${PATH}"
Then any pip install commands that follow in the Dockerfile will find /path/to/venv/bin/pip first and use that, which will install into that virtualenv and not the system python.
Here is an example Dockerfile leveraging several clever techniques to all you to run a full conda environment for every RUN stanza. You can use a similar approach to execute any arbitrary prep in a script file.
Note: there is a lot of nuance when it comes to login/interactive vs nonlogin/noninteractive shells, signals, exec, the way multiple args are handled, quoting, how CMD and ENTRYPOINT interact, and a million other things, so don't be discouraged if when hacking around with these things, stuff goes sideways. I've spent many frustrating hours digging through all manner of literature and I still don't quite get how it all clicks.
## Conda with custom entrypoint from base ubuntu image
## Build with e.g. `docker build -t monoconda .`
## Run with `docker run --rm -it monoconda bash` to drop right into
## the environment `foo` !
FROM ubuntu:18.04
## Install things we need to install more things
RUN apt-get update -qq &&\
apt-get install -qq curl wget git &&\
apt-get install -qq --no-install-recommends \
libssl-dev \
software-properties-common \
&& rm -rf /var/lib/apt/lists/*
## Install miniconda
RUN wget -nv https://repo.anaconda.com/miniconda/Miniconda3-4.7.12-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh && \
/opt/conda/bin/conda clean -tipsy && \
ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh
## add conda to the path so we can execute it by name
ENV PATH=/opt/conda/bin:$PATH
## Create /entry.sh which will be our new shell entry point. This performs actions to configure the environment
## before starting a new shell (which inherits the env).
## The exec is important! This allows signals to pass
RUN (echo '#!/bin/bash' \
&& echo '__conda_setup="$(/opt/conda/bin/conda shell.bash hook 2> /dev/null)"' \
&& echo 'eval "$__conda_setup"' \
&& echo 'conda activate "${CONDA_TARGET_ENV:-base}"' \
&& echo '>&2 echo "ENTRYPOINT: CONDA_DEFAULT_ENV=${CONDA_DEFAULT_ENV}"' \
&& echo 'exec "$#"'\
) >> /entry.sh && chmod +x /entry.sh
## Tell the docker build process to use this for RUN.
## The default shell on Linux is ["/bin/sh", "-c"], and on Windows is ["cmd", "/S", "/C"]
SHELL ["/entry.sh", "/bin/bash", "-c"]
## Now, every following invocation of RUN will start with the entry script
RUN conda update conda -y
## Create a dummy env
RUN conda create --name foo
## I added this variable such that I have the entry script activate a specific env
ENV CONDA_TARGET_ENV=foo
## This will get installed in the env foo since it gets activated at the start of the RUN stanza
RUN conda install pip
## Configure .bashrc to drop into a conda env and immediately activate our TARGET env
RUN conda init && echo 'conda activate "${CONDA_TARGET_ENV:-base}"' >> ~/.bashrc
ENTRYPOINT ["/entry.sh"]
I've dealing with a similar scenario for an application developed with Django web web framework and these are the steps that worked perfectly for me:
content of my Dockerfile
[mlazo#srvjenkins project_textile]$ cat docker/Dockerfile.debug
FROM malazo/project_textile_ubuntu:latest
ENV PROJECT_DIR=/proyectos/project_textile PROJECT_NAME=project_textile WRAPPER_PATH=/usr/share/virtualenvwrapper/virtualenvwrapper.sh
COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}
RUN echo "source ${WRAPPER_PATH}" > ~/.bashrc
SHELL ["/bin/bash","-c","-l"]
RUN mkvirtualenv -p $(which python3) ${PROJECT_NAME} && \
workon ${PROJECT_NAME} && \
pip3 install -r requirements.txt
EXPOSE 8000
ENTRYPOINT ["tests/container_entrypoint.sh"]
CMD ["public/manage.py","runserver","0:8000"]
content of the ENTRYPOINT file "tests/container_entrypoint.sh":
[mlazo#srvjenkins project_textile]$ cat tests/container_entrypoint.sh
#!/bin/bash
# *-* encoding : UTF-8 *-*
sh tests/deliver_env.sh
source ~/.virtualenvs/project_textile/bin/activate
exec python "$#"
finally, the way I deploy the container was :
[mlazo#srvjenkins project_textile]$ cat ./tests/container_deployment.sh
#!/bin/bash
CONT_NAME="cont_app_server"
IMG_NAME="malazo/project_textile_app"
[ $(docker ps -a |grep -i ${CONT_NAME} |wc -l) -gt 0 ] && docker rm -f ${CONT_NAME}
docker run --name ${CONT_NAME} -p 8000:8000 -e DEBUG=${DEBUG} -e MYSQL_USER=${MYSQL_USER} -e MYSQL_PASSWORD=${MYSQL_PASSWORD} -e MYSQL_HOST=${MYSQL_HOST} -e MYSQL_DATABASE=${MYSQL_DATABASE} -e MYSQL_PORT=${MYSQL_PORT} -d ${IMG_NAME}
I really hope this would be helpful for somebody else.
Greetings,
I had the same issue. If you also use a python base image you can change the shebang line in your shell script to #!/bin/bash.
See for example the container_entrypoint.sh from Manuel Lazo.

How can I get a secure system-wide oh-my-zsh configuration?

I'd like to have a system-wide oh-my-zsh setup, but I'm not sure what would be the "best" approach for this. It is not my intention to ask about personal preferences or the like, I'm just unsure whether the solutions below are:
ln my local user configuration somewhere doesn't seem right, because adding an exploit to my local cfg and therefore gain root permissions would be very easy.
Installing oh-my-zsh to /etc would be maybe also a security hole because I simply haven't written it by myself.
Simply writing my own personal .zshrc would be the last approach I would like to try out because it’s very time-consuming.
Any recommendations?
Unless I'm misunderstanding the marked answer from Caleb is just the normal per-user installation steps with adding a .zshrc file to the skel dir and changing the default new-user shell, but it doesn't actually work or really answer the question because each user still requires the oh-my-zsh dir/would still require each user to clone the oh-my-zsh dir into their own folder meaning it's not really installed system wide, it just automatically gives them a zshrc file and changes the default shell to zsh, but without oh-my-zsh in each user folder it will error out.
From what I understand of the question it's asking how to install oh-my-zsh system-wide aka have it installed in ONE place and not require manually messing around on each new user/having a git clone of oh-my-zsh on each user dir. Assuming that's the case, here's what I did based off Arch Linux's AUR Package I normally use but was looking for the same on a centos server, however this can be done on any distro. Credit goes to MarcinWieczorek and the other maintainers, I just adapted the below so can do the same on non-arch distros.
If you already have oh-my-zsh installed on root just skip to Step 3. This isn't distro specific just uses the AUR Patch File for zshrc
Step #1
Install zsh of course
Step #2
Install oh-my-zsh as root as normal (shows wget method, see Calebs answer for alternative)
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
Step #3
Move the install to /usr/share so is system-wide
#Copy zsh files to /usr/share for all uer access
mv /root/.oh-my-zsh /usr/share/oh-my-zsh
# Move into the dir and copy the zshrc template to zshrc (which will be the default for users)
cd /usr/share/oh-my-zsh/
cp templates/zshrc.zsh-template zshrc
# Nab the patch file from MarcinWieczorek's AUR Package and apply to the zshrc file
wget https://aur.archlinux.org/cgit/aur.git/plain/0001-zshrc.patch\?h\=oh-my-zsh-git -O zshrc.patch && patch -p1 < zshrc.patch
Now oh-my-zsh is installed globally and the user just needs that zshrc file. so NOW is where Caleb's answer comes in though just do the below as /etc/adduser.conf is only on debian whereas the below should be distro independent.
Step #4
Set it up to be the default on new users
# Create hard link to the zshrc file so it creates an actual independent copy on new users
sudo ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc
# Set default shell to zsh
sudo adduser -D -s /bin/zsh
Now that's a true installation of oh-my-zsh with all new users automatically having it applied with the /usr/share/oh-my-zsh/zshrc settings and no other steps needed.
Misc Notes
For any pre-existing users with oh-my-zsh:
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
You can set new user OMZ defaults in /usr/share/oh-my-zsh/zshrc
Auto Updates are disabled since new users do not have permissions to update the /usr/share/oh-my-zsh files
To update oh-my-zsh just cd to /usr/share/oh-my-zsh/ and run 'sudo git pull'
The oh-my-zsh cache will be handled per-user within each user dir under ~/.oh-my-zsh-cache/ (automatically created)
Fair Warning: this assumes a Debian style linux, but this should work on other forms as well. This also assumes you are starting from scratch.
Part 1, the install:
You will need to install zsh system wide, and not just for one user. (you may have already done this but I'll include it just to be comprehensive)
make sure you have installed zsh, simply: sudo apt-get install zsh
Follow the oh-my-zsh install guide or you can either:
use curl
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
use wget
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"
Part 2, Setting up zsh when new users are added:
You will need to make it so that new users default to zsh. In your /etc/adduser.conf file edit the line that says:
DSHELL=/bin/sh
to:
DSHELL=/bin/zsh
You should also change it for the /etc/default/useradd file, change the line:
SHELL=/bin/sh
to:
SHELL=/bin/zsh
Part 3, set your custom theme.
I have a custom theme file (here) that I wanted all users on the system to have. First, you should add the file to your .oh-my-zsh/themes folder:
cp your_custom_style.zsh-theme ~/.oh-my-zsh/themes
Next, edit your .zshrc file in your home directory, change the ZSH_THEME="default" to ZSH_THEME="your_custom_style"
Then, reload your .zshrc file with: . ~/.zshrc
Part 4, setting up new user's home directories.
We need to to place whatever files we want the new users to have in the /etc/skel directory, because this is what the system copies when it is creating new user's home directory. See this sys admin guide for details.
Copy your user's files (you may need to sudo):
cp -r .oh-my-zsh /etc/skel/
cp .zshrc /etc/skel
Now you will be able to add new users and they will have oh-my-zsh by
default with whatever custom theme you want them to have.
If you want to change all other existing user's shell to zsh, I would recommend reading this serverfault question.
If you want a system-wide install of Oh-My-Zsh, a convenient approach that overwrites the least number files is:
sudo git clone https://github.com/robbyrussell/oh-my-zsh.git /etc/oh-my-zsh
sudo cp /etc/oh-my-zsh/templates/zshrc.zsh-template /etc/skel/.zshrc
sudo mkdir -p /etc/skel/.oh-my-zsh/cache
Edit /etc/skel/.zshrc:
Edit the line export ZSH=$HOME/.oh-my-zsh (currently line 5)
Change the line to be:
export ZSH=/etc/oh-my-zsh
export ZSH_CACHE_DIR=~/.oh-my-zsh/cache
Then edit /etc/default/useradd and change the line SHELL=... to SHELL=/bin/zsh.
That's basically all (of course, git and zsh must be installed already).
To update a pre-existing user: login as them and cp /etc/skel/.zshrc ~/.zshrc
Update: Please do not edit this. I just rolled back an edit which completely botched it up!
Login as ROOT
Step 1: Install ZSH
# Download and extract ZSH
wget https://github.com/zsh-users/zsh/archive/zsh-5.8.tar.gz -P /tmp/demo/zsh
cd /tmp/demo/zsh
tar -xvzf zsh-*
cd zsh-zsh-5.8
# configure and make
sudo ./Util/preconfig
sudo ./configure
sudo make && sudo make install
# Add ZSH to the list of shells
echo /usr/local/bin/zsh | sudo tee -a /etc/shells
Step 2: Install oh-my-zsh
# If you're running the Oh My Zsh install script as part of an automated install,
# you can pass the flag --unattended to the install.sh script.
# This will have the effect of not trying to change the default shell, and also won't
# run zsh when the installation has finished.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
# Add oh-my-zsh to /usr/share
mv /root/.oh-my-zsh /usr/share
mv /usr/share/.oh-my-zsh /usr/share/oh-my-zsh
mv /root/.zshrc /usr/share/oh-my-zsh
mv /usr/share/oh-my-zsh/.zshrc /usr/share/oh-my-zsh/zshrc
# Modify zshrc to point to /usr/share/oh-my-zsh
sed -i 's|export ZSH="'"$HOME"'/.oh-my-zsh"|export ZSH="\/usr\/share\/oh-my-zsh"|g' /usr/share/oh-my-zsh/zshrc
Step 3: Add Extra (Optional - Look at the bottom for extra features)
Step 4: Create Symbolic link
# Create Symbolic Links to /etc/skel
sudo ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc
Step 5: Add oh-my-zsh for root
# Change shell to ZSH for root
echo "$USER" | chsh -s /usr/local/bin/zsh
Step 6: Add oh-my-zsh for user
# Change user
su - username
# Copy zshrc to $HOME for user
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
# Change shell to ZSH for user
echo "$USER" | chsh -s /usr/local/bin/zsh
OR
sudo -i -u username bash << EOF
cp /usr/share/oh-my-zsh/zshrc ~/.zshrc
echo username | chsh -s /usr/local/bin/zsh
EOF
EXTRA:
Change theme to powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/themes/powerlevel10k
sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="powerlevel10k\/powerlevel10k"/g' /usr/share/oh-my-zsh/zshrc
Enable Auto correction
sed -i 's/# ENABLE_CORRECTION="true"/ENABLE_CORRECTION="true"/g' /usr/share/oh-my-zsh/zshrc
Enable Auto suggestions and Syntax highlighting
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-/usr/share/oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
sed -i 's/plugins=(git)/plugins=(\n git\n zsh-autosuggestions\n zsh-syntax-highlighting\n)/' /usr/share/oh-my-zsh/zshrc
sed -i 's/plugins=(git)/plugins=(git)\nZSH_DISABLE_COMPFIX=true/' /usr/share/oh-my-zsh/zshrc
Add nord dircolors
git clone --depth=1 https://github.com/arcticicestudio/nord-dircolors.git /tmp/demo/dircolors
mv /tmp/demo/dircolors/src/dir_colors /usr/share/
cd /usr/share/
mv /usr/share/dir_colors /usr/share/.dir_colors
tee -a /usr/share/oh-my-zsh/zshrc >/dev/null <<'EOF'
test -r "/usr/share/.dir_colors" && eval $(dircolors /usr/share/.dir_colors)
EOF
I combined cFINNY's answer, reading and understanding the oh-my-zsh install script, the AUR patch in his answer, and fixing the broken adduser command to do this install in a FROM ubuntu:bionic (Ubuntu 18.04) Dockerfile :
RUN git clone \
-c core.eol=lf \
-c core.autocrlf=false \
-c fsck.zeroPaddedFilemode=ignore \
-c fetch.fsck.zeroPaddedFilemode=ignore \
-c receive.fsck.zeroPaddedFilemode=ignore \
--depth=1 \
--branch master \
https://github.com/ohmyzsh/ohmyzsh.git \
/usr/share/oh-my-zsh \
# Adapt zshrc template
&& cd /usr/share/oh-my-zsh/ \
&& cp templates/zshrc.zsh-template zshrc \
&& sed -i 's/export ZSH=$HOME\/.oh-my-zsh/export ZSH=\/usr\/share\/oh-my-zsh/g' zshrc \
&& sed -i 's/# DISABLE_AUTO_UPDATE="true"/DISABLE_AUTO_UPDATE="true"/g' zshrc \
&& sed -i 's/source $ZSH\/oh-my-zsh.sh//g' zshrc \
&& sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="bira"/g' zshrc \
&& echo '\n \
\n \
ZSH_CACHE_DIR=$HOME/.cache/oh-my-zsh \n \
if [[ ! -d $ZSH_CACHE_DIR ]]; then \n \
mkdir -p $ZSH_CACHE_DIR \n \
fi \n \
\n \
source $ZSH/oh-my-zsh.sh \n \
' >> zshrc \
# Copy zshrc template to $HOME on user creation
&& ln /usr/share/oh-my-zsh/zshrc /etc/skel/.zshrc \
# Setting the default shell for new users has no effect since:
# 1. The default shell is specified when creating new users in entrypoint
# 2. The `ade enter` command will execute `bash` anyways
&& sed -i 's/DSHELL=\/bin\/bash/DSHELL=\/bin\/zsh/g' /etc/adduser.conf
There's also a simple way to do this as well:
Login as the root user and install zsh
sudo su
apt-get install zsh
Then login as another user of the system:
su username
export ZSH=/home/username/.oh-my-zsh
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Follow same procedures for all users who want oh-my-zsh

how to install nodejs 0.10.26 from binaries in Ubuntu

I am new to linux and am trying to install nodejs latest version with binaries. The solutions I have looked up suggest the installation using apt-get on some private repositories(PPA), which I do not want to do.
So I ran the following commands:
wget http://nodejs.org/dist/v0.10.26/node-v0.10.26-linux-x64.tar.gz
tar -zxvf node-v0.10.26-linux-x64.tar.gz
mv node-v0.10.26-linux-x64 node-v0.10.26
sudo cp -r node-v0.10.26 /usr/local/src
After this, I don't really know what to do. I read an article which suggested created symbolic links, which I am kind of scared to mess up with without knowing the details.
Could you please give me a set of commands to run after this in order to install node with npm? I guess npm should be a part of this binary version.
The best way to install Node.js and have the latest version (or any other version that you prefer, be it LTS or "current") is to download the official binary bundle and uncompress it. A neat way to do it:
# Use version 0.10.26
$ NODE_VERSION="v0.10.26"
# To use a newer version, for example 6.10.3, use instead:
$ NODE_VERSION="v6.10.3"
$ curl -LO http://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.gz
$ tar xzf node-$NODE_VERSION-linux-x64.tar.gz
$ sudo cp -rp node-$NODE_VERSION-linux-x64 /usr/local/
$ sudo ln -s /usr/local/node-$NODE_VERSION-linux-x64 /usr/local/node
The basic idea is to move all the contents of the archive into /usr/local, then create a symlink in /usr/local/node pointing to the most recent version.
For enabling the use of the "node" executable from the command line without referencing the full path (/usr/local/node/bin/node), add /usr/local/node/bin to your $PATH (usually this involves altering the ~/.bash_profile or ~/.profile file; there's plenty of docs for how to do this).
If you need to update Node.js (suppose it's version 7.10.0), then, just extract the tarball in /usr/local and update the symbolic link so it points to the new one. You can then optionally remove the old folder.
May 2017 update
As of the "Creators Update", the commands above can now work also on Windows 10 using the "Windows Subsystem for Linux" (via bash). On Ubuntu on Windows 10, after creating the symlink like above, to add the folder to your $PATH add PATH="/usr/local/node/bin:$PATH" in the ~/.bashrc file.
I combined both of these answers for my docker container. I wanted the executable to be in the PATH already without me explicitly doing that.
#!/usr/bin/env bash
install_node() {
NODE_VERSION="v8.3.0"
curl -# "http://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz" | tar -xz
cp -pr "node-${NODE_VERSION}-linux-x64" "/usr/local/"
ln -s "/usr/local/node-${NODE_VERSION}-linux-x64" "/usr/local/node"
ln -s /usr/local/node/bin/* "/usr/local/bin"
rm -rf "node-${NODE_VERSION}-linux-x64"
}
install_node
You can extract the binary anywhere and use update-alternatives command which maintain symbolic links determining default commands for example this is on my laptop.
first i extract my node node-v10.16.3-linux-x64.tar.xz on /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/ folder :
xxxx#xxxxPC:.../WSL_Ubuntu/Downloads$ tar xvf node-v10.16.3-linux-x64.tar.xz
xxxx#xxxxPC:.../WSL_Ubuntu/Downloads$ cd node-v10.16.3-linux-x64/
then update-alternatives --install :
xxxx#xxxxPC:.../node-v10.16.3-linux-x64/bin$ sudo update-alternatives --install /home/wira/.local/bin/node node\
> /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/bin/node 60
update-alternatives: using /mnt/e/WSL_Ubuntu/Downloads/node-v10.16.3-linux-x64/bin/node to provide /home/wira/.local/bin/node (node) in auto mode
Now i use the node on terminal
xxxx#xxxxPC:.../node-v10.16.3-linux-x64/bin$ node --version
v10.16.3
You should also update-alternatives --install on npm binaries.
I think there is still a cleaner way
NODE_VERSION="v6.7.0"
# Download
curl -LO http://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.gz
# uncompress
tar xzf node-$NODE_VERSION-linux-x64.tar.gz
# selective copy
cp -R ./node-$NODE_VERSION-linux-x64/bin/* /usr/local/bin
cp -R ./node-$NODE_VERSION-linux-x64/lib/* /usr/local/lib
cp -R ./node-$NODE_VERSION-linux-x64/include/* /usr/local/include
cp -R ./node-$NODE_VERSION-linux-x64/share/* /usr/local/share
Node should be working now
$ node -e 'console.log("HI")'
HI
Hope it helps

Resources