Using Node odbc with Microsoft Access - docker

I am attempting to write a containerized Node application that intakes Microsoft Access databases and accesses the data within. I want to put the application in a docker container and wish to use npm odbc to interact with Access. I don't have much experience creating containers so much of this has been a learning process.
I am struggling to get odbc installed and configured for Access. Per the documentation that I linked, there are three requirements for odbc.
Install unixODBC and unixODBC-devel
Install ODBC drivers for target database
Define odbc.ini and odbcinst.ini
I am struggling to get any amount of odbc functionality working, so I assume the issue is that I'm not configuring the environment correctly. Here is my base Dockerfile where I define the container environment. Running the AccessDatabaseEngine.exe file returns a Not Found error, even though I'm pretty sure that the file should exist there. For now, I have commented out the line. The application code runs from a different set of Dockerfiles that build off this one.
# Use Ubuntu OS as base image
FROM ubuntu:latest
# Set env vars
ENV NPM_CONFIG_LOGLEVEL info
# odbc requirement #1
# Install unixODBC, unixODBC-devel, and curl
RUN apt-get update
RUN apt-get -y install unixodbc
RUN apt-get -y install unixodbc-dev
RUN apt-get -y install curl
# Download & install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_12.x | bash
RUN apt-get -y install nodejs
# odbc requirement #2
# Install ODBC drivers for Access database
RUN curl -LJO https://download.microsoft.com/download/2/4/3/24375141-E08D-4803-AB0E-10F2E3A07AAA/AccessDatabaseEngine.exe
RUN cp AccessDatabaseEngine.exe /bin/
RUN chmod +x /bin/AccessDatabaseEngine.exe
# RUN ['/bin/AccessDatabaseEngine.exe'] # Error: #14 0.249 /bin/sh: 1 [/bin/AccessDatabaseEngine.exe]: not found
# Run node
CMD [ "node" ]
In my application, I attempt to use odbc like this. The connection string for odbc requirement #3 was found here:
// Test function to test out npm odbc
exports.export = async (file) => {
// odbc requirement #3
// Make Access connection
const conn = await odbc.connect(`Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=${file.path}`);
// Execute test query
const res = await conn.query('SELECT 1');
console.log(JSON.stringify(res));
}
I feel pretty good about my implementation of odbc requirements #1 and #3, but I am struggling with #2 (Install ODBC drivers for target database). Not only am I struggling to run the AccessDatabaseEngine.exe, but I'm also not 100% sure that it's even the correct file to be trying to install. I ran into this and that seems like it might the odbc driver that I need. However, I tried dockerizing the code they gave and ran into more issues.
Again, I want to create a containerized Node application that uses the ODBC npm library to access the data within a Microsoft Access database. Does anybody have any experience doing this? Any help would be appreciated. Thanks ahead of time.

As it was said in the comments. I'm grasping at the wrong straws here. I cannot download Access Drivers onto my Linux machine. Per the driver system requirements here, I must use a Windows OS.

Related

How to install VS Code extensions in a Dockerfile?

Is there a way to install VS Code extensions in a Dockerfile?
Apparently, while most browser-based VS Code forks (including openvscode-server) do not permit headless installation of VS Code extensions (as seen from my other answer), it is possible to do such automated installs using docker build in one of them: Code Server (code-server), like in this sample Dockerfile:
FROM ubuntu:22.04
RUN apt update && apt install -y curl
# install VS Code (code-server)
RUN curl -fsSL https://code-server.dev/install.sh | sh
# install VS Code extensions
RUN code-server --install-extension redhat.vscode-yaml \
--install-extension ms-python.python
Relevant fragment of the docker build log:
[..]
---> Running in 59eea050a2db
[2022-11-13T10:13:58.762Z] info Wrote default config file to ~/.config/code-server/config.yaml
Installing extensions...
Installing extension 'redhat.vscode-yaml'...
Installing extension 'ms-python.python'...
Extension 'redhat.vscode-yaml' v1.10.1 was successfully installed.
Extension 'ms-python.python' v2022.16.1 was successfully installed.
[..]
Per the VS Code Documentation, the extensions property is specific to VS Code and can only be configured using .devcontainer.
The best you can do is if the extension has a CLI, you can install that. For example,
RUN npm install prettier -D --save-exact
Then use npx:
npx prettier --check .
This is sadly disallowed by design, as confirmed by this error message you will see in your docker build log when you attempt to run code --install-extension or openvscode-server --install-extension:
Command is only available in WSL or inside a Visual Studio Code terminal.
This is also confirmed (and tagged) as being as designed by one of VS Code Remote devs in this GitHub issue:
This is correct the 'vs code server CLI' is only available from the integrated terminal.
So VS Code Remote or even openvscode-server make it impossible to automate installs of first- or third-party extensions for this popular Microsoft IDE, unless you run their custom terminal inside their closed-source IDE, which normally entails buying a license for their GUI-based closed-source operating system as well;)

Installing Informix CSDK in an Ubuntu Docker container

I'm trying to install ibm.csdk.4.50.FC3.LNX in a Docker container based on Ubuntu 18.
I run in the container the installation file as follows:
root#mycontainer:/usr/src/ibm.csdk.4.50.FC3.LNX# ./installclientsdk -i console
But I get this error:
One or more prerequisite system libraries are not installed on your
computer. Install libdl.so.2, libcrypt.so.1, libpam.so.0,
libstdc++.so.6, libm.so.6, libgcc_s.so.1, libc.so.6, libncurses.so.5
and then restart the IBM Informix installation program.
The installation cannot succeed until the minimum requirements are
met. For more information about the prerequisites, see your
Installation Guide or check with your System Administrator.
However those files are already in the container in the following paths:
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libcrypt.so.1
/lib/x86_64-linux-gnu/libpam.so.0
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libncurses.so.5
How can I install it?
Running apt install unixodbc-dev seems fixing.
You might want to install also unixodbc
We have similar issue where we are running shell script which runs dbaccess inside the docker container. but as we run the docker as root user it is trying to use root user to connect to the informix db server. is there a way we can configure user name and password for dbaccess to use the configured userId instead of root.

Ubuntu, shopsys install via composer, docker, still crashing

I wanna install shopsys via composer and docker, as is recommended.
https://github.com/shopsys/shopsys/blob/master/docs/installation/installation-using-docker-linux.md
I installed git, php-fpm (configured), postgres (configured), composer, docker, docker-compose.
sudo apt install git
sudo apt install php7.2-fpm
sudo apt install postgresql
sudo apt install composer
sudo apt install docker-ce
sudo apt install docker-compose
Everything ok.
I added my user to docker group.
sudo usermod -a -G docker $(whoami)
Ok.
Next I made folder /var/www/html/shopsys, created project shopsys via composer.
composer create-project shopsys/project-base --no-install --keep-vcs
cd project-base/
Then I run this in /var/www/html/shopsys/project-base.
./scripts/install.sh
Everything seems to be ok, until this.
[RuntimeException]
/var/www/html/vendor does not exist and could not be created.
I set rights to 777 for folder /var/www/html, and run it again, but same problem.
The I run this.
sudo composer install
It shows me this error.
....Exception\InvalidConfigurationException]
Invalid configuration for path "monolog.handlers.main": You can only use ex
cluded_http_codes/excluded_404s with a FingersCrossedHandler definition
In ScriptHandler.php line 294:
An error occurred when executing the "'shopsys:domains-urls:configure'" command:
In BaseNode.php line 319:
...\Exception\InvalidConfigurationException]
Invalid configuration for path "monolog.handlers.main": You can only use ex
cluded_http_codes/excluded_404s with a FingersCrossedHandler definition
...
etc., error is quite ugly.
Last error when i run script install.sh.
file_put_contents(/var/www/html/vendor/composer/installed.json): failed to open stream: Permission denied
But this folder does not exist.
ls: cannot access '/var/www/html/vendor/': No such file or directory
Just question, where could be the problem?
Is possible to download sources from some link, extract it, configure and display in web browser with easy way, for example as wordpress?
Thanks.
To solve problem with vendor:
It seems that your UID and GID is different than default 1000, that is set in docker-compose.yml for Linux by default.
To solve your issue you can continue by step 3 in https://github.com/shopsys/shopsys/blob/master/docs/installation/installation-using-docker-linux.md#3-set-the-uid-and-gid-to-allow-file-access-in-mounted-volumes
You found issue with installation script, I have created issue on GitHub.
To solve problem with Invalid configuration for path "monolog.handlers.main":
Currently there is problem with new minor version (3.4.0) of symfony/monolog-bundle that created BC break. There is already created issue about this problem and there is already merged fix in Shopsys master.
To solve problem in your project you have to add
"symfony/monolog-bundle": ">=3.4.0", in conflict section in your composer.json file and then run composer install again.
We are trying to answer questions on stackoverflow as soon as possible, but we also have Slack where is many users and you might get your question answered much faster.

pyodbc not working in web-service container, Azure Model Management

I am trying to create a web-service via Azure Model Management and am struggling.
I've followed the instructions and have managed to operationalize locally in a Docker container. My 'score.py' file includes a query to a SQL database using pyodbc. This functions perfectly when I test this on my local environment using the ML Workbench, however once this has been deployed in a Docker container I come across this error:
'Response Content': b'(\'01000\', "[01000] [unixODBC][Driver Manager]Can\'t open lib \'ODBC Driver 13 for SQL Server\' : file not found (0) (SQLDriverConnect)")'
I have included pyodbc in my conda_dependencies.yml.
Has anyone got any suggestions? Is there any further dependencies that I need to include?
Azure seem to have recently added the ability to customize container images using what they call a 'Docker Steps file'. I have practically no experience in Docker, but after reading this question i tried including a 'Docker Steps file' containing this:
ADD odbcinst.ini /etc/odbcinst.ini
RUN apt-get update
RUN apt-get install -y tdsodbc unixodbc-dev
RUN apt install unixodbc-bin -y
RUN apt-get clean -y
However i understand 'ADD' commands are not possible in this type of file, so this seems to have made no difference.
Hopefully this this all makes sense! Any advice would be very much appreciated! I hope I'm not the only one stumbling my way through Azure ML!
EDIT:
I'm still stuck, but making progress...
I accessed the root of the container using:
docker exec -ti -u root container_name bash
From here I ran 'odbcinst -j`, resulting in:
unixODBC 2.3.6
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
I couldn't seem to actually locate odbc.ini so i followed these instructions for installing 'ODBC Driver 13' for Ubuntu 16.04. Now when I run the service i get a different error:
{'Error': MlCliError({'Error': 'Error occurred while attempting to score service myapp.', 'Response Code': 502, 'Response Content': b'<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body bgcolor="white">\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx/1.10.3 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n', 'Response Headers': {'Content-Length': '182', 'Content-Type': 'text/html', 'Date': 'Wed, 18 Apr 2018 14:06:30 GMT', 'Server': 'nginx/1.10.3 (Ubuntu)', 'Connection': 'keep-alive'}},), 'Azure-cli-ml Version': '0.1.0b2'}
I have also tried altering my score.py file to return: pyodbc.drivers() this results in a blank '[]'

envsubst command getting stuck in a container

I have a requirement that before an application runs, some part of it needs to read the environmental variable. For this I have the following docker file
FROM nodesource/jessie:0.12.7
# install gettext for envsubst
RUN apt-get update
RUN apt-get install -y gettext-base
# cache package.json and node_modules to speed up builds
ADD package.json package.json
RUN npm install
# Add source files
ADD src src
# Substiture value for backend endpoint env var
RUN envsubst < src/js/envapp.js > src/js/app.js
ADD node_modules node_modules
EXPOSE 8000
CMD ["npm","start"]
The above envsubst line reads (should read) an env variable $MYENV and substitutes it. But when I open the file app.js, its empty.
I checked if the environmental variable exists in the container and it does. Any reason its value is not read and substituted?
I also tried the same command in teh container and it works. It only does not work when I run the image
This is likely because $MYENV is not available for envsubst when you run the image.
Each RUN command runs on its own shell.
From the Docker documentations:
RUN (the command is run in a shell - /bin/sh -c - shell form)
You need to source your profile as well, for example if the $MYENV environment variable is available in the .bashrc file, you can modify your Dockerfile like this:
RUN source ~/.bashrc && envsubst < src/js/envapp.js > src/js/app.js
I encountered the same issues, and after much research and fishing through the internet. I managed to find a few work arounds to this issue. Below I'll list them and identifiable risks at the time of this "Answer post"
Solutions:
1.) apt-get install -y gettext its a standard GNU package language library, one of these libraries that it includes is envsubst` and I can confirm that it works for docker UBUNTU:latest and it should work for every flavored version.
2.) npm install envsub dependent on the "use case" - this approach would be better supported by node based projects.
3.) enstub cli project lib in my opinion it seems a bit overkill to downloading a custom cli from a random stranger but, it's also another option.
Risk:
apt-get install -y gettext:
1.) gettext - this approach would NOT be ideal for VM's as with any package library, it requires maintenance and updates as time passes. However, this isn't necessary for docker because once an a container is initialized and up and running we can create a bashscript to add the package, substitute env vars and then remove the package.
2.) It's a bad idea for VM's because it can be used to execute arbitrary code
npm install ensub
1.) envsub - updating packages and this approach wouldn't be ideal if your dealing with a different stack and not using nodejs.
NOTE:
There's also a PHP version for those developing a PHP application and it seems to work PHP's cli if you need a custom environment.
Resources:
GetText package library info: https://www.gnu.org/software/gettext/
GetText Risk - https://ubuntu.com/security/notices/USN-3815-2
PHP-GetText - apt-get install -y php-gettext
Custom ensubst cli: https://github.com/a8m/envsubst
I suggest that since your are using Node, you use the npm envsub module.
This module is well tested and is developed with docker in mind.
It avoids the need for relying on other dependencies when you already have the full Node arsenal at your fingertips.
envsub is described as
envsub is envsubst for NodeJS
NodeJS global CLI module providing file-level environment variable substitution via Handlebars
I am the author of the package. I think you will enjoy it.
I had some issues with envsubst in Docker.
For some reasons envsubst doesn't work when I try to copy the output in the same file. For example, this is not working:
RUN envsubst < file.conf > file.conf
But when I when I tried to use a temp file the issue disappeared:
RUN envsubst < file.conf > file.conf.temp && cp -f file.conf.temp file.conf

Resources