Add support for static linking of sqlx
`sqlx` requires linking against OpenSSL twice: - `sqlx-macros` needs to link against OpenSSL as a shared libary for use at compile time. - `sqlx` needs to link against OpenSSL a static library for use at runtime. You can find the details here: https://github.com/launchbadge/sqlx/issues/670 https://github.com/sfackler/rust-openssl/issues/1337 We go with the fix proposed by @sfackler, and add a test program that we can use to verify everything works correctly. We remove a few `OPENSSL`-related variables that were added 4 years ago, and that no longer appear to be needed.
This commit is contained in:
parent
9f6efa542f
commit
727d912b3b
|
@ -67,7 +67,7 @@ RUN apt-get update && \
|
|||
curl -fLO https://github.com/EmbarkStudios/cargo-deny/releases/download/$CARGO_DENY_VERSION/cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz && \
|
||||
tar xf cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz && \
|
||||
mv cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl/cargo-deny /usr/local/bin/ && \
|
||||
rm -rf cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz
|
||||
rm -rf cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl cargo-deny-$CARGO_DENY_VERSION-x86_64-unknown-linux-musl.tar.gz
|
||||
|
||||
# Static linking for C++ code
|
||||
RUN sudo ln -s "/usr/bin/g++" "/usr/bin/musl-g++"
|
||||
|
@ -142,11 +142,8 @@ RUN echo "Building libpq" && \
|
|||
cd ../../bin/pg_config && make && sudo make install && \
|
||||
rm -r /tmp/*
|
||||
|
||||
ENV OPENSSL_DIR=/usr/local/musl/ \
|
||||
OPENSSL_INCLUDE_DIR=/usr/local/musl/include/ \
|
||||
DEP_OPENSSL_INCLUDE=/usr/local/musl/include/ \
|
||||
OPENSSL_LIB_DIR=/usr/local/musl/lib/ \
|
||||
OPENSSL_STATIC=1 \
|
||||
ENV X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR=/usr/local/musl/ \
|
||||
X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_STATIC=1 \
|
||||
PQ_LIB_STATIC_X86_64_UNKNOWN_LINUX_MUSL=1 \
|
||||
PG_CONFIG_X86_64_UNKNOWN_LINUX_GNU=/usr/bin/pg_config \
|
||||
PKG_CONFIG_ALLOW_CROSS=true \
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
[![Docker Image](https://img.shields.io/docker/pulls/ekidd/rust-musl-builder.svg?maxAge=2592000)](https://hub.docker.com/r/ekidd/rust-musl-builder/)
|
||||
|
||||
[Source on GitHub](https://github.com/emk/rust-musl-builder)
|
||||
|
||||
## What is this?
|
||||
|
||||
Do you want to compile a completely static Rust binary with no external dependencies? If so, try:
|
||||
|
@ -13,7 +15,7 @@ rust-musl-builder cargo build --release
|
|||
|
||||
This command assumes that `$(pwd)` is readable and writable by uid 1000, gid 1000. At the moment, it doesn't attempt to cache libraries between builds, so this is best reserved for making final release builds.
|
||||
|
||||
For a more realistic example, see the `Dockerfile` for [examples/using-diesel](./examples/using-diesel).
|
||||
For a more realistic example, see the `Dockerfile` for [examples/using-diesel](./examples/using-diesel) [examples/using-sqlx](./examples/using-sqlx).
|
||||
|
||||
## Deploying your Rust application
|
||||
|
||||
|
@ -36,7 +38,7 @@ In general, we provide the following tagged Docker images:
|
|||
Rust, please file an issue.
|
||||
|
||||
At a minimum, each of these images should be able to
|
||||
compile [examples/using-diesel](./examples/using-diesel).
|
||||
compile [examples/using-diesel](./examples/using-diesel) and [examples/using-sqlx](./examples/using-sqlx).
|
||||
|
||||
[comp]: https://rust-lang.github.io/rustup-components-history/index.html
|
||||
|
||||
|
@ -94,8 +96,6 @@ This image also supports the following extra goodies:
|
|||
If your application uses OpenSSL, you will also need to take a few extra steps to make sure that it can find OpenSSL's list of trusted certificates, which is stored in different locations on different Linux distributions. You can do this using [`openssl-probe`](https://crates.io/crates/openssl-probe) as follows:
|
||||
|
||||
```rust
|
||||
extern crate openssl_probe;
|
||||
|
||||
fn main() {
|
||||
openssl_probe::init_ssl_cert_env_vars();
|
||||
//... your code
|
||||
|
|
|
@ -9,3 +9,4 @@ diesel = { version = "1", features = ["postgres", "sqlite"] }
|
|||
libsqlite3-sys = { version = "*", features = ["bundled"] }
|
||||
# Needed for Postgres.
|
||||
openssl = "*"
|
||||
openssl-probe = "0.1.2"
|
||||
|
|
|
@ -46,6 +46,8 @@ where
|
|||
}
|
||||
|
||||
fn main() {
|
||||
openssl_probe::init_ssl_cert_env_vars();
|
||||
|
||||
println!("Hello, world!");
|
||||
|
||||
// Only run our database example if we have a database. Otherwise, we just
|
||||
|
|
1
examples/using-sqlx/.dockerignore
Normal file
1
examples/using-sqlx/.dockerignore
Normal file
|
@ -0,0 +1 @@
|
|||
target
|
1265
examples/using-sqlx/Cargo.lock
generated
Normal file
1265
examples/using-sqlx/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
examples/using-sqlx/Cargo.toml
Normal file
12
examples/using-sqlx/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "using-sqlx"
|
||||
version = "0.1.0"
|
||||
authors = ["Eric Kidd <git@randomhacks.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
openssl-probe = "0.1.2"
|
||||
sqlx = { version = "0.4.0-beta.1", default-features = false, features = ["runtime-tokio", "macros", "offline", "postgres"] }
|
||||
tokio = { version = "0.2", features = ["macros"] }
|
25
examples/using-sqlx/Dockerfile
Normal file
25
examples/using-sqlx/Dockerfile
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- mode: dockerfile -*-
|
||||
#
|
||||
# An example Dockerfile showing how to build a Rust executable using this
|
||||
# image, and deploy it with a tiny Alpine Linux container.
|
||||
|
||||
# You can override this `--build-arg BASE_IMAGE=...` to use different
|
||||
# version of Rust or OpenSSL.
|
||||
ARG BASE_IMAGE=ekidd/rust-musl-builder:latest
|
||||
|
||||
# Our first FROM statement declares the build environment.
|
||||
FROM ${BASE_IMAGE} AS builder
|
||||
|
||||
# Add our source code.
|
||||
ADD --chown=rust:rust . ./
|
||||
|
||||
# Build our application.
|
||||
RUN cargo build --release
|
||||
|
||||
# Now, we need to build our _real_ Docker container, copying in `using-sqlx`.
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates
|
||||
COPY --from=builder \
|
||||
/home/rust/src/target/x86_64-unknown-linux-musl/release/using-sqlx \
|
||||
/usr/local/bin/
|
||||
CMD /usr/local/bin/using-sqlx
|
12
examples/using-sqlx/docker-compose.yml
Normal file
12
examples/using-sqlx/docker-compose.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
version: "2.0"
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
volumes:
|
||||
- cargo:/home/rust/.cargo
|
||||
- target:/home/rust/src/target
|
||||
|
||||
volumes:
|
||||
cargo: {}
|
||||
target: {}
|
23
examples/using-sqlx/sqlx-data.json
Normal file
23
examples/using-sqlx/sqlx-data.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"db": "PostgreSQL",
|
||||
"bf54a84704792059fc3a494889dce274bb09f5cadc8c7be61a9b85abbceb001f": {
|
||||
"query": "SELECT $1::INTEGER AS value",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "value",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
23
examples/using-sqlx/src/main.rs
Normal file
23
examples/using-sqlx/src/main.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use std::env;
|
||||
|
||||
use sqlx::{Connection, postgres::PgConnection};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), sqlx::Error> {
|
||||
openssl_probe::init_ssl_cert_env_vars();
|
||||
|
||||
let url = env::var("POSTGRES_URL")
|
||||
.unwrap_or_else(|_| "postgresql://postgres@localhost/postgres".to_owned());
|
||||
|
||||
// Create a connection.
|
||||
let mut conn = PgConnection::connect(&url).await?;
|
||||
|
||||
// Make a simple query using the `query!` macro.
|
||||
let row = sqlx::query!("SELECT $1::INTEGER AS value", 2i32)
|
||||
.fetch_one(&mut conn)
|
||||
.await?;
|
||||
|
||||
assert_eq!(row.value, Some(2));
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
set -euo pipefail
|
||||
|
||||
# Make sure we can build some of our more important test images.
|
||||
for EXAMPLE in using-diesel; do
|
||||
for EXAMPLE in using-diesel using-sqlx; do
|
||||
docker build \
|
||||
--build-arg BASE_IMAGE="$IMAGE_NAME" \
|
||||
-t rust-musl-builder-"$EXAMPLE" \
|
||||
|
|
14
test-image
14
test-image
|
@ -41,6 +41,20 @@ fi
|
|||
echo -e '[PASS] ARMhf binary is statically linked.\n'
|
||||
"
|
||||
|
||||
# Make sure we can build a static executable using `sqlx`.
|
||||
docker build -t rust-musl-builder-using-sqlx examples/using-sqlx
|
||||
docker run --rm rust-musl-builder-using-sqlx sh -c "
|
||||
set -euo pipefail
|
||||
|
||||
echo -e '--- Test case for sqlx:'
|
||||
echo 'ldd says:'
|
||||
if ldd /usr/local/bin/using-sqlx; then
|
||||
echo '[FAIL] Executable is not static!' 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e '[PASS] using-sqlx binary is statically linked.\n'
|
||||
"
|
||||
|
||||
# Make sure we can build a static executable using `git2`.
|
||||
docker build -t rust-musl-builder-linking-with-git2 examples/linking-with-git2
|
||||
docker run --rm rust-musl-builder-linking-with-git2 bash -c "
|
||||
|
|
Loading…
Reference in a new issue