Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for command line of dart at Linux #146

Closed
iampopal opened this issue Mar 11, 2023 · 17 comments
Closed

Support for command line of dart at Linux #146

iampopal opened this issue Mar 11, 2023 · 17 comments

Comments

@iampopal
Copy link

Hello Simolus,
We want to run our server which has a database of sqlitecipher in the server with dart command line
https://dart.dev/tutorials/server/cmdline

When we run our app with flutter as the flutter repository contains sqlcipher_flutter_libs: ^0.5.4 in .yaml file, our flatter app works all good with the local flutter server.

Now we want to run our server in a container with Dockerfile so we need command line capability at pure dart code.

You can look at the command line simple here: (https://dart.dev/tutorials/server/cmdline)
Please help us how we can have sqlcipher in our command line dart app.

@iampopal
Copy link
Author

Can you please help us with which command to run and get the libsqlcipher.so file or provide us libsqlcipher.so file to include it with our command line.

@simolus3
Copy link
Owner

Could you post the Dockerfile you're using at the moment? There are many ways to get a libsqlcipher.so for most Linux distributions - depending on the one you use as the basis for your container, I can suggest a way to install it.

@iampopal
Copy link
Author

Here is my dockerfile:

FROM dart:stable AS build

# Install sqlcipher
RUN apt update; \
    apt install -y sqlcipher

# double checking that sqlcipher is installed successfully 
RUN sqlcipher --version

# Resolve app dependencies.
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get

# Copy app source code and AOT compile it.
COPY . .

# Ensure packages are still up-to-date if anything has changed
# RUN dart pub get
RUN dart pub get --offline
RUN dart compile exe bin/server.dart -o bin/server

# Changing current directry to /app/bin
WORKDIR /app/bin

# Start server.
ENV PORT 8080
EXPOSE 8080

# Runing Dart Server
CMD ["./server"]

@iampopal
Copy link
Author

After not getting able to get a good result from Dockerfile so tried to install Kali-Linux arm64 on my M1
then
tried to compile https://github.com/sqlcipher/sqlcipher and install
then
copied libsqlcipher.so from /usr/local/lib
and posted it in bin folder of dart server and called it with:

      open.overrideFor(
        OperatingSystem.linux,
        () {
          return DynamicLibrary.open('./bin/libsqlcipher.so');
        },
      );

But I am still getting the error of file is not database which is because of sqlcipher not exists.

static bool hasCipherDb(database) {
   hasCipher = database.select('PRAGMA cipher_version;').isNotEmpty;
   return hasCipher;
 }

did double checked by hasCipherDb(db) it still return false

@iampopal
Copy link
Author

Our encrypted sqlcipher db work all good in: Android, Windows, iOS and MacOS

We really need it to work on Dockerfile so we can host our db in serverless platform.

thank you.

@simolus3
Copy link
Owner

This works for me (note the sqlcipher-dev instead of sqlcipher):

FROM dart:stable AS build

# Install sqlcipher
RUN apt update; \
    apt install -y sqlcipher-dev

# Resolve app dependencies.
WORKDIR /app
...

In the container, I'm just using this override:

open.overrideForAll(() {
  return DynamicLibrary.open('libsqlcipher.so');
});

If you want to make the image smaller at runtime, you can also use the recommended FROM scratch setup recommended by the Dart image:

FROM dart:stable AS build

# Install sqlcipher
RUN apt update; \
    apt install -y libsqlcipher-dev

# Resolve app dependencies.
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get

# Copy app source code and AOT compile it.
COPY . .

# Ensure packages are still up-to-date if anything has changed
# RUN dart pub get
RUN dart pub get --offline
RUN dart compile exe bin/main.dart -o bin/server

FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /app/bin/server /app/bin/
COPY --from=build /usr/lib/x86_64-linux-gnu/libsqlcipher.so /lib/
COPY --from=build /usr/lib/x86_64-linux-gnu/libcrypto.so.* /lib/

# Changing current directry to /app/bin
WORKDIR /app/bin

# Runing Dart Server
CMD ["./server"]

@iampopal
Copy link
Author

Thank you so much for your contribution, it worked all good thank you so much.

@iampopal
Copy link
Author

@simolus3 I am using the drift package and have a very amazing experience with it.
Thank you so much for providing these awesome packages

@iampopal
Copy link
Author

@simolus3
I am back again

The good news is that libsqlcipher.so exists and the function of:

static bool hasCipherDb(database) {
   hasCipher = database.select('PRAGMA cipher_version;').isNotEmpty;
   return hasCipher;
 }

Return true when opening a new or old database which is good news and sqlcipher exists.

but

Now here is one more issue with opening the old database:
When opening the old database I get the following error:

SqliteException(26): file is encrypted or is not a database, file is encrypted or is not a database (code 26)
Causing statement: SELECT * FROM \"users\

@iampopal
Copy link
Author

This my new Dockerfile

FROM dart:stable AS build

# Install sqlcipher
RUN apt update; \
    apt install -y libsqlcipher-dev

# Resolve app dependencies.
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get

# Copy app source code and AOT compile it.
COPY . .

# Ensure packages are still up-to-date if anything has changed
# RUN dart pub get
RUN dart pub get --offline
RUN dart compile exe bin/server.dart -o bin/server

FROM scratch
COPY --from=build /runtime/ /
COPY --from=build /usr/lib/x86_64-linux-gnu/libsqlcipher.so /lib/
COPY --from=build /usr/lib/x86_64-linux-gnu/libcrypto.so.* /lib/
COPY --from=build /app/bin/server /app/bin/
COPY --from=build /app/bin/data.db /app/bin/

# Changing current directry to /bin
WORKDIR /app

# Setting Port
ENV PORT 8080
EXPOSE 8080

# Runing Dart Server
CMD ["./bin/server"]

@iampopal
Copy link
Author

I did try opening the database with 'DB Browser for SQLite'
When opening a Database with SQLCipher 4 Default: It works all Good.
When opening a Database with SQLCipher 3 Default: It does not work.

So I am thinking that which version of the sqlcipher:
apt install -y libsqlcipher-dev
Is installing..

@iampopal
Copy link
Author

iampopal commented Mar 12, 2023

I have tried to check the version of sqlcipher in my local directory and container by calling:
var res = database.select('PRAGMA cipher_version;').toString();
The version number in my local directory where everything works all fine is: [{cipher_version: 4.5.3 community}]
The version in the docker file where db failed to open is: [{cipher_version: 3.4.1}]

@iampopal
Copy link
Author

Can you with how can I download the new version sqlcipher and share dockerfile back?

@simolus3
Copy link
Owner

Seems like you'll have to download and compile SQLCipher yourself then. You can take a look at my CMakeLists.txt for inspiration - you'll also have to install OpenSSL and a compiler toolchain. I'm not sure if you want to do this in the container, you can probably also compile a libsqlcipher.so outside of the container and then COPY it with a Dockerfile.

I can't give you a fully working solution here unfortunately - but if you compile SQLCipher on an x64 machine (if the container runtime is x64 as well), it should work.

@iampopal
Copy link
Author

Thank you @simolus3.
here is my updated Dockerfile which works well with dart image:

FROM dart:stable AS build

RUN apt update; \
    DEBIAN_FRONTEND=noninteractive apt install -y build-essential git gcc g++ make libffi-dev libssl-dev tcl; \
    cd /root; \
    git clone https://github.com/sqlcipher/sqlcipher.git; \
    mkdir bld; \
    cd bld; \
    ../sqlcipher/configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"; \
    make; make install; \
    apt remove -y build-essential git gcc g++ make libffi-dev libssl-dev tcl; \
    apt autoremove -y; \
    rm -rf ~/bld ~/sqlcipher

RUN cp /usr/local/lib/libsqlcipher.so /lib/

# Resolve app dependencies.
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get

# Copy app source code and AOT compile it.
COPY . .

# Ensure packages are still up-to-date if anything has changed
RUN dart pub get --offline
RUN dart compile exe bin/server.dart -o bin/server

# FROM scratch
# COPY --from=build /runtime/ /
# COPY --from=build /app/bin/server /app/bin/
# COPY --from=build /app/bin/data.db /app/bin/

# Changing current directry to /bin
WORKDIR /app

# Setting Port
ENV PORT 8080
EXPOSE 8080

# Runing Dart Server
CMD ["./bin/server"]

As you can see above I have commented the FROM scratch part because I still don't know what files shall I copy from above container.

# FROM scratch
# COPY --from=build /runtime/ /
# COPY --from=build /app/bin/libsqlcipher.so /app/bin/
# COPY --from=build /app/bin/libsqlcipher.la /app/bin/
# COPY --from=build /app/bin/libsqlcipher.so.0 /app/bin/
# COPY --from=build /app/bin/libsqlcipher.so.0.8.6 /app/bin/
# COPY --from=build /usr/local/lib/libsqlcipher.so /lib/
# COPY --from=build /app/bin/server /app/bin/
# COPY --from=build /app/bin/data.db /app/bin/

I have tried to connect to the docker container with ssh and downloaded the libsqlciopher.so and a couple of other files associated with it but From scratch still not able to load sqlcipher but the dart image where I installed the sqlcipher by compiling works all good.

@iampopal
Copy link
Author

Please help me tell me which files are required for sqlcipher.so to work fine.

so I will download these needed file by ssh scp and place it in the repo docker file and will not needed to always compile sqlcipher.

@iampopal
Copy link
Author

I have downloaded the following files from the docker server by remote ssh scp:

/usr/local/lib/libsqlcipher.so
/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1

  1. Where shall I place them From scratch to work?
  2. Are any other files also needed for sqlcipher to work?
  3. Do I still need to compile in dockerfile after downloading and placing in repo 2 files?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants