Why does setfacl not work in docker container? - file

I have trouble with ACL in my docker container.
As you can see below, I set read/write permissions for user "ts" on "/opt/transfer_station/webapp/logs". This works for the folder "/opt/transfer_station/webapp/logs" but not for the file /opt/transfer_station/webapp/logs/debug.log in it. Why does it not work?
[root#lx-ts logs]# setfacl -Rdm u:ts:rw,g:ts:rw /opt/transfer_station/webapp/logs
[root#lx-ts logs]# echo $?
0
[root#lx-ts logs]# getfacl /opt/transfer_station/webapp/logs
getfacl: Removing leading '/' from absolute path names
# file: opt/transfer_station/webapp/logs
# owner: apache
# group: apache
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:apache:rw-
default:user:ts:rw-
default:group::r-x
default:group:apache:rw-
default:group:ts:rw-
default:mask::rwx
default:other::r-x
[root#lx-ts logs]# getfacl /opt/transfer_station/webapp/logs/debug.log
getfacl: Removing leading '/' from absolute path names
# file: opt/transfer_station/webapp/logs/debug.log
# owner: root
# group: root
user::rw-
group::r--
other::r--
[root#lx-ts logs]# whoami
root
Btw. I tried it with docker option OPTIONS='--storage-driver=devicemapper' and without it. SELinux is in permissive mode and does therefore not block anything.
If I attach to the container, create a test file in the folder, the ACLs are inherited as I expect:
[root#lx-ts transfer_station]# touch webapp/logs/test
[root#lx-ts transfer_station]# getfacl webapp/logs/test
# file: webapp/logs/test
# owner: root
# group: root
user::rw-
user:apache:rw-
user:ts:rw-
group::r-x #effective:r--
group:apache:rw-
group:ts:rw-
mask::rw-
other::r--
I am running Centos 7.1 and Docker version 1.7.1, build 446ad9b/1.7.1.
I have also added the CAP_FOWNER to the container (using --cap-add=FOWNER) but that does not solve the problem neither.
Any ideas?

Got it:
setfacl -Rm u:ts:rw,g:ts:rw /opt/transfer_station/webapp/logs
setfacl -d is for directories only. I had to remove it to make it work :/

Related

Use enviroment variables in dockerized react app

The goal I am trying to achieve is to build a docker image (with a react app within) that is using environment variables from the host.
Planned workflow:
Build the docker image locally
Upload the docker image
Call command docker-compose up
I want the environment variable REACT_APP_SOME_ENV_VARIABLE of the system (where the image is hosted) to be usable by the react app.
Current solution:
// App.js
function App() {
return (
<p>SOME_ENV_VARIABLE = {process.env.REACT_APP_SOME_ENV_VARIABLE}</p>
);
}
# Dockerfile
FROM node:13.12.0-alpine as build-step
# Install the app
RUN mkdir /app
WORKDIR /app
COPY package.json /app
RUN npm install --silent
# Build the app
COPY . /app
RUN npm run-script build
# Create nginx server and copy build there
FROM nginx:1.19-alpine
COPY --from=build-step /app/build /usr/share/nginx/html
# docker-compose.yml
version: '3.5'
services:
react-env:
image: react-env
ports:
- 80:80/tcp
environment:
- REACT_APP_SOME_ENV_VARIABLE=FOO
What am I doing wrong and how do I fix it?
This was solved by using an NGINX docker package, inject the compiled React production code into the NGINX html folder, then modify the docker-entrypoint.sh file.
FROM nginx:1.19-alpine
COPY --from=build-step /app/build /usr/share/nginx/html
COPY ./docker/docker-entrypoint.sh /docker-entrypoint.sh
Then in that file add the following code at the end of the old script
#!/bin/sh
#!/bin/sh
# vim:sw=4:ts=4:et
set -e
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
exec 3>&1
else
exec 3>/dev/null
fi
if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
echo >&3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"
echo >&3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
find "/docker-entrypoint.d/" -follow -type f -print | sort -n | while read -r f; do
case "$f" in
*.sh)
if [ -x "$f" ]; then
echo >&3 "$0: Launching $f";
"$f"
else
# warn on shell scripts without exec bit
echo >&3 "$0: Ignoring $f, not executable";
fi
;;
*) echo >&3 "$0: Ignoring $f";;
esac
done
echo >&3 "$0: Configuration complete; ready for start up"
else
echo >&3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
fi
fi
# Set up endpoint for env retrieval
echo "window._env_ = {" > /usr/share/nginx/html/env_config.js
# Collect enviroment variables for react
eval enviroment_variables="$(env | grep REACT_APP.*=)"
# Loop over variables
env | grep REACT_APP.*= | while read -r line;
do
printf "%s',\n" $line | sed "s/=/:'/" >> /usr/share/nginx/html/env_config.js
# Notify the user
printf "Env variable %s' was injected into React App. \n" $line | sed "0,/=/{s//:'/}"
done
# End the object creation
echo "}" >> /usr/share/nginx/html/env_config.js
echo "Enviroment Variable Injection Complete."
exec "$#"
Functionality:
This will find all environment variable sent to the docker container running the frontend to extract all variables starting with REACT_APP and add them to a file named env_config.js.
All you need to do in the react app is to load that script file, then access the environment variables using window._env_.<property>.
DISCLAIMER
Environment variables injected with this method is fully readable by anyone using the site. This is not a secure method for sensitive information. Only use this for things such as "where is the backend api endpoint" or other non-sensitive information that can be extracted just as easily.
In your approach, the environment variables are injected when the container starts, and by that time your App is built and docker image is created, and also you cannot access process.env on client side. Therefore to access them on client side, we have to do the below steps.
You must be using webpack in your React App for bundling and other stuff.
So in you webpack.config.js, declare your environment variable REACT_APP_SOME_ENV_VARIABLE using Define plugin which will result in declaring the variables as global variables for the app.
Your webpack config should look something like this:
const path = require("path");
const webpack = require("webpack");
module.exports = {
target: "web",
performance: {
hints: false,
},
node: {
fs: "empty"
},
entry: "./src/index.js",
output: {
path: path.join(__dirname, "/build"),
filename: "[name].[contenthash].js"
},
module: {
rules: [
//your rules
]
},
plugins: [
new webpack.DefinePlugin({
"envVariable": JSON.stringify(process.env.REACT_APP_SOME_ENV_VARIABLE),
}),
],
};
And in your App, you can use the variable like this
// App.js
function App() {
return (
<p>SOME_ENV_VARIABLE = {envVariable}</p>
);
}
NOTE: Make sure before RUN npm run-script build command is run, your environment variables are injected to docker container.
For that you should declare your environment variables in DockerFile using ENV before RUN npm run-script build step.

Error when creating Directory and creating files using touch in UNIX

I am trying to create a directory structure in Unix. I made the directory using mkdir command with -p option but when i use "touch" to create files i get hit with the "No such file or directory error"
The code i tried .
mkdir -p livingthings{birds/{flyingbirds,nonflyingbirds},plants,animals/{mammals,reptiles}}
touch livingthings/{birds/{flyingbirds/{stork,eagle,eider},nonflyingbirds/{kiwi,ostrich,penguin}},plants/{carrot,cabbage,daisy},animals/{mammals/{jaguar,dog,tiger},reptiles/{alligator,skink,turtle}}}
This is the error which pops out
Help much appreciated.
UPDATE :
After adding the "/" i get one error now that is telling
touch: cannot touch 'livingthings/animals/reptiles/turtle': No such file or directory .:
The issue is you missed the slash after livingthings in mkdir -p livingthings/{birds..... not mkdir -p livingthings{birds.... Because of this it creates a directory named livingthingsbirds instead of livingthings/birds. But then in your touch command u r using livingthings/ so thats why it cant find that directory.

Warning: Return code of 127 for check of service was out of bounds. Make sure the plugin you're trying to run actually exists

I'm trying to use the phanton-js plugin for Nagios:
https://github.com/hggh/phantomjs-nagios
but despite me double checking the set-up, I'm getting
"Return code 127 is out of bounds : Plugin may be missing"
The plugin file exists in the plugins folder:
# stat /usr/lib64/nagios/plugins/check_http_load_time.rb
File: `/usr/lib64/nagios/plugins/check_http_load_time.rb'
Size: 9108 Blocks: 24 IO Block: 4096 regular file
Device: fc01h/64513d Inode: 275201 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
I can execute it when su'd to the nagios user locally:
-bash-4.1$ whoami
nagios
-bash-4.1$ /usr/lib64/nagios/plugins/phantomjs-nagios/check_http_load_time.rb -u https://google.com -w 2 -c 3
OK: https://google.com load time: 0.43
This is how it is defined in the checkcommands.cfg file:
define command {
command_name check_web_page_load_time
command_line $USER1$/check_http_load_time.rb -u $ARG1$ -w $ARG2$ -c $ARG3$
}
and this is the service definition
define service {
use generic-service
host_name test_host
service_description https://google.com web load time
check_command check_web_page_load_time!https://google.com!2!3
contact_groups support-emails
}
I've restarted nagios and confirmed that the config check passes.
Am I missing something obvious?
edit:
plugin file is located in 2 folders:
/usr/lib64/nagios/plugins/check_http_load_time.rb
and
/usr/lib64/nagios/plugins/phantomjs-nagios/check_http_load_time.rb
both files are identical, both can be executed by the nagios user successfully and neither location works with command definition. I tried calling it with full path and with the $USR1$ variable, which points to the standard location where all the other plugins are located
/usr/lib64/nagios/plugins/
Manged to eventually solve it. The error message was not very helpful, as problem was with the environment variables of the nagios user.
The original script had the following shebang:
#!/usr/bin/env ruby
After changing it to the actual location of ruby binary the script works:
#!/usr/local/rvm/rubies/ruby-2.5.1/bin/ruby
Still surprised that it worked when su'd to the Nagios user.

weblogic integrated instance start from command line

The test server instance in jdeveloper of WLS how do I start from command line without having to start jdeveloper for it.
I imported and deployed few projects to internal WLS and to keep them running so would prefer to start / stop using command line. I have used all default settings for install.
Below you see my middleware dir where jdeveloper and domains are installed. The domain has no shell files to start/stop the instance.
[root#NVMBD01VSR383 Middleware]# cd user_projects/applications/DefaultDomain/
[root#NVMBD01VSR383 DefaultDomain]# ls
[root#NVMBD01VSR383 DefaultDomain]# ls -al
total 8
drwxr-x--- 2 mhood mhood 4096 Dec 22 15:05 .
drwxr-x--- 3 mhood mhood 4096 Dec 22 15:05 ..
[root#NVMBD01VSR383 DefaultDomain]# pwd
/home/mhood/Oracle/Middleware/user_projects/applications/DefaultDomain
[root#NVMBD01VSR383 DefaultDomain]# cd ..
[root#NVMBD01VSR383 applications]# ls
DefaultDomain
[root#NVMBD01VSR383 applications]# cd ..
[root#NVMBD01VSR383 user_projects]# cd ..
[root#NVMBD01VSR383 Middleware]# ls
domain-registry.xml jdk160_24 modules patch_jdev1111 registry.dat user_projects wlserver_10.3
jdeveloper logs oracle_common patch_wls1035 registry.xml utils
I though see some files as below:
/home/mhood/Oracle/Middleware/wlserver_10.3/common/bin
[root#NVMBD01VSR383 bin]# ls
commEnv.sh config.sh setPatchEnv.sh unpack.sh wlscontrol.sh wlst.sh
config_builder.sh pack.sh startManagedWebLogic.sh upgrade.sh wlsifconfig.sh
[root#NVMBD01VSR383 bin]# cd ..
[root#NVMBD01VSR383 common]# ls
bin deployable-libraries lib nodemanager quickstart templates wlst
[root#NVMBD01VSR383 common]# ls nodemanager/
nodemanager.domains
Regards,
Miten.
[mhood#NVMBD01VSR383 DefaultDomain]$ ls
autodeploy config edit.lok init-info logs pending servers startWebLogic.sh
bin console-ext fileRealm.properties lib oracle security shutdown.py tmp
[mhood#NVMBD01VSR383 DefaultDomain]$ pwd
/home/mhood/.jdeveloper/system11.1.1.7.40.64.93/DefaultDomain
[mhood#NVMBD01VSR383 DefaultDomain]$
Its in .jdeveloper directory. Its hidden.

Script to change ownership of folders in Plesk vhosts

I'm looking for some help in creating a shell script in Linux to perform a batch ownership change for certain folders in a Plesk environment where the owner:group is apache:apache.
I want to change the owner:group to :psacln.
The FTP user can be ascertained by looking at the owner of the httpdocs folder.
^this is the section I'm having trouble with.
If I was to set all owners to be the same, I could do a one-line:
find /var/www/vhosts/*/httpdocs -user apache -group apache -exec chown user:psacln {} \;
Can anyone help plug the user in to this command?
Thanks
Figured it out... for those who may want to use it in the future:
for dir in /var/www/vhosts/*
do
dir=${dir%*/}
permissions=`stat -c '%U' ${dir##*/}/httpdocs`
find ${dir##*/}/httpdocs -user apache -group apache -exec chown $permissions {} \;
done
Since stat doesn't work on al unices in the same way, I thought I would share my script to set the ownership of all websites to the correct owners in Plesk (tested on Plesk 11, 11.5, 12 and 12.5):
cd /var/www/vhosts/
for f in *; do
if [[ -d "$f" && ! -L "$f" ]]; then
# Get necessary variables
FOLDERROOT="/var/www/vhosts/"
FOLDERPATH="/var/www/vhosts/$f/"
FTPUSER="$(ls -ld /var/www/vhosts/$f/ | awk '{print $3}')"
# Set correct rights for current website, if website has hosting!
cd $FOLDERPATH
if [ -d "$FOLDERPATH/httpdocs" ]; then
chown -R $FTPUSER:psacln httpdocs
chmod -R g+w httpdocs
find httpdocs -type d -exec chmod g+s {} \;
# Print success message
echo "Done... $FTPUSER is now correct owner of $FOLDERPATH."
fi
# Make sure we are back at the root, so we can continue looping
cd $FOLDERROOT
fi
done
\\\
Explanation of code:
Go to vhosts folder
Loop through websites
Store vhosts path, because we are using cdin a loop
If httpdocsfolders exists for the current website, than
set the correct rights of httpdocs and
all underlying folders
Show succes message
cd back to vhosts folder, so we can continue looping
\\\

Resources